From 03c6c80332d42d9aaf7951e96481cc0fbf6c7d36 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 9 May 2016 21:53:01 -0700 Subject: [PATCH 001/165] Factor out some SD card info formatting. --- firmware/application/ui_sd_card_debug.cpp | 54 ++++++++++------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/firmware/application/ui_sd_card_debug.cpp b/firmware/application/ui_sd_card_debug.cpp index 28d164e2..0281d6be 100644 --- a/firmware/application/ui_sd_card_debug.cpp +++ b/firmware/application/ui_sd_card_debug.cpp @@ -272,6 +272,26 @@ void SDCardDebugView::focus() { button_ok.focus(); } +static std::string format_3dot3_string(const uint32_t value_in_thousandths) { + if( value_in_thousandths < 1000000U ) { + const uint32_t thousandths_part = value_in_thousandths % 1000; + const uint32_t integer_part = value_in_thousandths / 1000U; + return to_string_dec_uint(integer_part, 3) + "." + to_string_dec_uint(thousandths_part, 3, '0'); + } else { + return "HHH.HHH"; + } +} + +static std::string format_bytes_size_string(uint64_t value) { + static const std::array suffix { { ' ', 'K', 'M', 'G', 'T' } }; + size_t suffix_index = 1; + while( (value >= 1000000U) && (suffix_index < suffix.size()) ) { + value /= 1000U; + suffix_index++; + } + return format_3dot3_string(value) + " " + suffix[suffix_index] + "B"; +} + void SDCardDebugView::on_status(const sd_card::Status) { text_bus_width_value.set(""); text_card_mode_value.set(""); @@ -306,48 +326,20 @@ void SDCardDebugView::on_status(const sd_card::Status) { text_block_size_value.set(to_string_dec_uint(block_device_info.blk_size, 5)); text_block_count_value.set(to_string_dec_uint(block_device_info.blk_num, 9)); const uint64_t capacity = block_device_info.blk_size * uint64_t(block_device_info.blk_num); - if( capacity >= 1000000000 ) { - const uint32_t capacity_mb = capacity / 1000000U; - const uint32_t fraction_gb = capacity_mb % 1000; - const uint32_t capacity_gb = capacity_mb / 1000U; - text_capacity_value.set( - to_string_dec_uint(capacity_gb, 3) + "." + - to_string_dec_uint(fraction_gb, 3, '0') + " GB" - ); - } else { - const uint32_t capacity_kb = capacity / 1000U; - const uint32_t fraction_mb = capacity_kb % 1000; - const uint32_t capacity_mb = capacity_kb / 1000U; - text_capacity_value.set( - to_string_dec_uint(capacity_mb, 3) + "." + - to_string_dec_uint(fraction_mb, 3, '0') + " MB" - ); - } + text_capacity_value.set(format_bytes_size_string(capacity)); } } } static std::string format_ticks_as_ms(const halrtcnt_t value) { const uint32_t us = uint64_t(value) * 1000000U / halGetCounterFrequency(); - const uint32_t ms_frac = us % 1000U; - const uint32_t ms_int = us / 1000U; - if( ms_int < 1000 ) { - return to_string_dec_uint(ms_int, 3) + "." + to_string_dec_uint(ms_frac, 3, '0'); - } else { - return "HHH.HHH"; - } + return format_3dot3_string(us); } static std::string format_bytes_per_ticks_as_mib(const size_t bytes, const halrtcnt_t ticks) { const uint32_t bps = uint64_t(bytes) * halGetCounterFrequency() / ticks; const uint32_t kbps = bps / 1000U; - const uint32_t mbps_frac = kbps % 1000U; - const uint32_t mbps_int = kbps / 1000U; - if( mbps_int < 1000 ) { - return to_string_dec_uint(mbps_int, 3) + "." + to_string_dec_uint(mbps_frac, 3, '0'); - } else { - return "HHH.HHH"; - } + return format_3dot3_string(kbps); } void SDCardDebugView::on_test() { From 95581f8c27fa706f76a1ce4e4b443d06d50a8ee9 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 9 May 2016 21:55:06 -0700 Subject: [PATCH 002/165] FatFs disk_ioctl(GET_BLOCK_SIZE) unimplemented, return correct value. --- .../chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c b/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c index 6adcdc20..7f090f16 100755 --- a/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c +++ b/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c @@ -232,7 +232,7 @@ DRESULT disk_ioctl ( *((WORD *)buff) = MMCSD_BLOCK_SIZE; return RES_OK; case GET_BLOCK_SIZE: - *((DWORD *)buff) = 256; /* 512b blocks in one erase block */ + *((DWORD *)buff) = 1; /* Unknown, TODO: implement? */ return RES_OK; #if _USE_ERASE case CTRL_ERASE_SECTOR: From 51b680c3bd396d6f32623d6fc49a113d4b75d440 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 9 May 2016 21:55:57 -0700 Subject: [PATCH 003/165] Implement FatFs disk_ioctl MMC_GET_{TYPE,CSD}. --- .../os/various/fatfs_bindings/fatfs_diskio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c b/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c index 7f090f16..d6cd3b1f 100755 --- a/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c +++ b/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs_diskio.c @@ -10,6 +10,8 @@ #include "ch.h" #include "hal.h" +#include + #include "diskio.h" #if HAL_USE_MMC_SPI && HAL_USE_SDC @@ -212,6 +214,12 @@ DRESULT disk_ioctl ( case GET_SECTOR_SIZE: *((WORD *)buff) = MMCSD_BLOCK_SIZE; return RES_OK; + case MMC_GET_TYPE: + *((BYTE *)buff) = SDCD1.cardmode; + return RES_OK; + case MMC_GET_CSD: + memcpy(buff, &SDCD1.csd, sizeof(SDCD1.csd)); + return RES_OK; #if _USE_ERASE case CTRL_ERASE_SECTOR: mmcErase(&MMCD1, *((DWORD *)buff), *((DWORD *)buff + 1)); @@ -234,6 +242,12 @@ DRESULT disk_ioctl ( case GET_BLOCK_SIZE: *((DWORD *)buff) = 1; /* Unknown, TODO: implement? */ return RES_OK; + case MMC_GET_TYPE: + *((BYTE *)buff) = SDCD1.cardmode; + return RES_OK; + case MMC_GET_CSD: + memcpy(buff, &SDCD1.csd, sizeof(SDCD1.csd)); + return RES_OK; #if _USE_ERASE case CTRL_ERASE_SECTOR: sdcErase(&SDCD1, *((DWORD *)buff), *((DWORD *)buff + 1)); From cc9c5acc3cf94b0536ebfd4245b384fd64f9f619 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 9 May 2016 22:42:54 -0700 Subject: [PATCH 004/165] Remove SD card debug "detected" field. --- firmware/application/ui_sd_card_debug.cpp | 4 ---- firmware/application/ui_sd_card_debug.hpp | 12 ------------ 2 files changed, 16 deletions(-) diff --git a/firmware/application/ui_sd_card_debug.cpp b/firmware/application/ui_sd_card_debug.cpp index 0281d6be..f07982e4 100644 --- a/firmware/application/ui_sd_card_debug.cpp +++ b/firmware/application/ui_sd_card_debug.cpp @@ -227,8 +227,6 @@ namespace ui { SDCardDebugView::SDCardDebugView(NavigationView& nav) { add_children({ { &text_title, - &text_detected_title, - &text_detected_value, &text_bus_width_title, &text_bus_width_value, &text_card_mode_title, @@ -305,8 +303,6 @@ void SDCardDebugView::on_status(const sd_card::Status) { text_test_read_rate_value.set(""); const bool is_inserted = sdcIsCardInserted(&SDCD1); - text_detected_value.set(is_inserted ? "Yes" : " No"); - if( is_inserted ) { const auto card_width_flags = LPC_SDMMC->CTYPE & 0x10001; size_t card_width = 0; diff --git a/firmware/application/ui_sd_card_debug.hpp b/firmware/application/ui_sd_card_debug.hpp index a573f3a1..86ab36bb 100644 --- a/firmware/application/ui_sd_card_debug.hpp +++ b/firmware/application/ui_sd_card_debug.hpp @@ -49,18 +49,6 @@ private: "SD Card", }; - static constexpr size_t detected_characters = 3; - - Text text_detected_title { - { 0, 3 * 16, (8 * 8), 16 }, - "Detected", - }; - - Text text_detected_value { - { 240 - (detected_characters * 8), 3 * 16, (detected_characters * 8), 16 }, - "", - }; - static constexpr size_t bus_width_characters = 1; Text text_bus_width_title { From 91ae692f902f9f77148335e25c4ec23bc2a32cb6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 9 May 2016 22:44:50 -0700 Subject: [PATCH 005/165] SD debug display CSD value. --- firmware/application/ui_sd_card_debug.cpp | 21 ++++++++++--- firmware/application/ui_sd_card_debug.hpp | 37 +++++++++++++++-------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/firmware/application/ui_sd_card_debug.cpp b/firmware/application/ui_sd_card_debug.cpp index f07982e4..a340c26b 100644 --- a/firmware/application/ui_sd_card_debug.cpp +++ b/firmware/application/ui_sd_card_debug.cpp @@ -27,6 +27,7 @@ #include "lfsr_random.hpp" #include "ff.h" +#include "diskio.h" #include "ch.h" #include "hal.h" @@ -227,12 +228,15 @@ namespace ui { SDCardDebugView::SDCardDebugView(NavigationView& nav) { add_children({ { &text_title, + &text_csd_title, + &text_csd_value_3, + &text_csd_value_2, + &text_csd_value_1, + &text_csd_value_0, &text_bus_width_title, &text_bus_width_value, &text_card_mode_title, &text_card_mode_value, - // &text_csd_title, - // &text_csd_value, &text_block_size_title, &text_block_size_value, &text_block_count_title, @@ -293,7 +297,10 @@ static std::string format_bytes_size_string(uint64_t value) { void SDCardDebugView::on_status(const sd_card::Status) { text_bus_width_value.set(""); text_card_mode_value.set(""); - // text_csd_value.set(""); + text_csd_value_0.set(""); + text_csd_value_1.set(""); + text_csd_value_2.set(""); + text_csd_value_3.set(""); text_block_size_value.set(""); text_block_count_value.set(""); text_capacity_value.set(""); @@ -315,7 +322,13 @@ void SDCardDebugView::on_status(const sd_card::Status) { text_bus_width_value.set(card_width ? to_string_dec_uint(card_width, 1) : "X"); text_card_mode_value.set("0x" + to_string_hex(SDCD1.cardmode, 8)); - // text_csd_value.set("0x" + to_string_hex(SDCD1.csd, 8)); + + std::array csd; + disk_ioctl(0, MMC_GET_CSD, csd.data()); + text_csd_value_3.set(to_string_hex(csd[3], 8)); + text_csd_value_2.set(to_string_hex(csd[2], 8)); + text_csd_value_1.set(to_string_hex(csd[1], 8)); + text_csd_value_0.set(to_string_hex(csd[0], 8)); BlockDeviceInfo block_device_info; if( sdcGetInfo(&SDCD1, &block_device_info) == CH_SUCCESS ) { diff --git a/firmware/application/ui_sd_card_debug.hpp b/firmware/application/ui_sd_card_debug.hpp index 86ab36bb..80e37468 100644 --- a/firmware/application/ui_sd_card_debug.hpp +++ b/firmware/application/ui_sd_card_debug.hpp @@ -49,6 +49,31 @@ private: "SD Card", }; + Text text_csd_title { + { 0, 3 * 16, (8 * 8), 16 }, + "CSD", + }; + + Text text_csd_value_3 { + { 240 - ((8 + 1 + 8) * 8), 3 * 16, (8 * 8), 16 }, + "", + }; + + Text text_csd_value_2 { + { 240 - (8 * 8), 3 * 16, (8 * 8), 16 }, + "", + }; + + Text text_csd_value_1 { + { 240 - ((8 + 1 + 8) * 8), 4 * 16, (8 * 8), 16 }, + "", + }; + + Text text_csd_value_0 { + { 240 - (8 * 8), 4 * 16, (8 * 8), 16 }, + "", + }; + static constexpr size_t bus_width_characters = 1; Text text_bus_width_title { @@ -73,18 +98,6 @@ private: "", }; - // static constexpr size_t csd_characters = 10; - - // Text text_csd_title { - // { 0, 7 * 16, (3 * 8), 16 }, - // "CSD", - // }; - - // Text text_csd_value { - // { 240 - (csd_characters * 8), 7 * 16, (csd_characters * 8), 16 }, - // "", - // }; - static constexpr size_t block_size_characters = 5; Text text_block_size_title { From 4c57c1205f53824bc5715db0a3c15d2cec100b2b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 9 May 2016 22:49:26 -0700 Subject: [PATCH 006/165] SD debug display more informative card type. --- firmware/application/ui_sd_card_debug.cpp | 24 +++++++++++++++++++---- firmware/application/ui_sd_card_debug.hpp | 10 +++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/firmware/application/ui_sd_card_debug.cpp b/firmware/application/ui_sd_card_debug.cpp index a340c26b..668c814b 100644 --- a/firmware/application/ui_sd_card_debug.cpp +++ b/firmware/application/ui_sd_card_debug.cpp @@ -235,8 +235,8 @@ SDCardDebugView::SDCardDebugView(NavigationView& nav) { &text_csd_value_0, &text_bus_width_title, &text_bus_width_value, - &text_card_mode_title, - &text_card_mode_value, + &text_card_type_title, + &text_card_type_value, &text_block_size_title, &text_block_size_value, &text_block_count_title, @@ -296,7 +296,7 @@ static std::string format_bytes_size_string(uint64_t value) { void SDCardDebugView::on_status(const sd_card::Status) { text_bus_width_value.set(""); - text_card_mode_value.set(""); + text_card_type_value.set(""); text_csd_value_0.set(""); text_csd_value_1.set(""); text_csd_value_2.set(""); @@ -321,7 +321,23 @@ void SDCardDebugView::on_status(const sd_card::Status) { } text_bus_width_value.set(card_width ? to_string_dec_uint(card_width, 1) : "X"); - text_card_mode_value.set("0x" + to_string_hex(SDCD1.cardmode, 8)); + + // TODO: Implement Text class right-justify! + BYTE card_type; + disk_ioctl(0, MMC_GET_TYPE, &card_type); + + std::string formatted_card_type; + switch(card_type & SDC_MODE_CARDTYPE_MASK) { + case SDC_MODE_CARDTYPE_SDV11: formatted_card_type = "SD V1.1"; break; + case SDC_MODE_CARDTYPE_SDV20: formatted_card_type = "SD V2.0"; break; + case SDC_MODE_CARDTYPE_MMC: formatted_card_type = "MMC"; break; + default: formatted_card_type = "???"; break; + } + + if( card_type & SDC_MODE_HIGH_CAPACITY ) { + formatted_card_type += ", SDHC"; + } + text_card_type_value.set(formatted_card_type); std::array csd; disk_ioctl(0, MMC_GET_CSD, csd.data()); diff --git a/firmware/application/ui_sd_card_debug.hpp b/firmware/application/ui_sd_card_debug.hpp index 80e37468..d051fd3c 100644 --- a/firmware/application/ui_sd_card_debug.hpp +++ b/firmware/application/ui_sd_card_debug.hpp @@ -86,15 +86,15 @@ private: "", }; - static constexpr size_t card_mode_characters = 10; + static constexpr size_t card_type_characters = 13; - Text text_card_mode_title { + Text text_card_type_title { { 0, 6 * 16, (9 * 8), 16 }, - "Card mode", + "Card type", }; - Text text_card_mode_value { - { 240 - (card_mode_characters * 8), 6 * 16, (card_mode_characters * 8), 16 }, + Text text_card_type_value { + { 240 - (card_type_characters * 8), 6 * 16, (card_type_characters * 8), 16 }, "", }; From 85a6ecd5dc2bf2ec118f6f0c329bda4255c7b4a7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 10 May 2016 11:02:42 -0700 Subject: [PATCH 007/165] Missing "using namespace". --- firmware/baseband/baseband_thread.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index 88d77ef0..053b5a3a 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -30,6 +30,7 @@ #include "rssi.hpp" #include "i2s.hpp" +using namespace lpc43xx; #include "proc_am_audio.hpp" #include "proc_nfm_audio.hpp" From b82eff51dd855828a5920a47af768c15e7d7966d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 10 May 2016 14:12:37 -0700 Subject: [PATCH 008/165] Refactor of capture buffer management between cores. Instead of copying data into and out of FIFO, passing buffer pointers between cores that are sized to match preferred/ideal SD card write size. --- firmware/application/analog_audio_app.hpp | 2 +- firmware/application/capture_app.hpp | 2 +- firmware/application/capture_thread.cpp | 48 +++++++------- firmware/application/capture_thread.hpp | 4 +- firmware/application/ui_record_view.cpp | 10 +-- firmware/application/ui_record_view.hpp | 8 +-- firmware/baseband/Makefile | 1 + firmware/baseband/stream_input.cpp | 76 +++++++++++++++++++++++ firmware/baseband/stream_input.hpp | 43 ++++--------- firmware/common/message.hpp | 59 +++++++++++++++--- 10 files changed, 180 insertions(+), 73 deletions(-) create mode 100644 firmware/baseband/stream_input.cpp diff --git a/firmware/application/analog_audio_app.hpp b/firmware/application/analog_audio_app.hpp index ebef06e3..0da7a7ad 100644 --- a/firmware/application/analog_audio_app.hpp +++ b/firmware/application/analog_audio_app.hpp @@ -143,7 +143,7 @@ private: RecordView record_view { { 0 * 8, 2 * 16, 30 * 8, 1 * 16 }, - "AUD_????", RecordView::FileType::WAV, 12, 2, + "AUD_????", RecordView::FileType::WAV, 4096, 4 }; spectrum::WaterfallWidget waterfall; diff --git a/firmware/application/capture_app.hpp b/firmware/application/capture_app.hpp index bc896f9e..6ece4b89 100644 --- a/firmware/application/capture_app.hpp +++ b/firmware/application/capture_app.hpp @@ -78,7 +78,7 @@ private: RecordView record_view { { 0 * 8, 2 * 16, 30 * 8, 1 * 16 }, - "BBD_????", RecordView::FileType::RawS16, 14, 1, + "BBD_????", RecordView::FileType::RawS16, 16384, 3 }; spectrum::WaterfallWidget waterfall; diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index 6bccea57..7d1eb557 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -31,20 +31,29 @@ public: ~StreamOutput(); size_t available() { - return fifo->len(); + return fifo_buffers_full->len(); } - size_t read(void* const data, const size_t length) { - return fifo->out(reinterpret_cast(data), length); + StreamBuffer* get_buffer() { + StreamBuffer* p { nullptr }; + fifo_buffers_full->out(p); + return p; } - static FIFO* fifo; + bool release_buffer(StreamBuffer* const p) { + p->empty(); + return fifo_buffers_empty->in(p); + } + + static FIFO* fifo_buffers_empty; + static FIFO* fifo_buffers_full; private: CaptureConfig* const config; }; -FIFO* StreamOutput::fifo = nullptr; +FIFO* StreamOutput::fifo_buffers_empty = nullptr; +FIFO* StreamOutput::fifo_buffers_full = nullptr; StreamOutput::StreamOutput( CaptureConfig* const config @@ -53,11 +62,13 @@ StreamOutput::StreamOutput( shared_memory.baseband_queue.push_and_wait( CaptureConfigMessage { config } ); - fifo = config->fifo; + fifo_buffers_empty = config->fifo_buffers_empty; + fifo_buffers_full = config->fifo_buffers_full; } StreamOutput::~StreamOutput() { - fifo = nullptr; + fifo_buffers_full = nullptr; + fifo_buffers_empty = nullptr; shared_memory.baseband_queue.push_and_wait( CaptureConfigMessage { nullptr } ); @@ -69,9 +80,9 @@ Thread* CaptureThread::thread = nullptr; CaptureThread::CaptureThread( std::unique_ptr writer, - size_t write_size_log2, - size_t buffer_count_log2 -) : config { write_size_log2, buffer_count_log2 }, + size_t write_size, + size_t buffer_count +) : config { write_size, buffer_count }, writer { std::move(writer) } { // Need significant stack for FATFS @@ -90,29 +101,22 @@ CaptureThread::~CaptureThread() { void CaptureThread::check_fifo_isr() { // TODO: Prevent over-signalling by transmitting a set of // flags from the baseband core. - const auto fifo = StreamOutput::fifo; + const auto fifo = StreamOutput::fifo_buffers_full; if( fifo ) { chEvtSignalI(thread, EVT_MASK_CAPTURE_THREAD); } } msg_t CaptureThread::run() { - const size_t write_size = 1U << config.write_size_log2; - const auto write_buffer = std::make_unique(write_size); - if( !write_buffer ) { - return false; - } - StreamOutput stream { &config }; while( !chThdShouldTerminate() ) { - if( stream.available() >= write_size ) { - if( stream.read(write_buffer.get(), write_size) != write_size ) { - return false; - } - if( !writer->write(write_buffer.get(), write_size) ) { + if( stream.available() ) { + auto buffer = stream.get_buffer(); + if( !writer->write(buffer->data(), buffer->size()) ) { return false; } + stream.release_buffer(buffer); } else { chEvtWaitAny(EVT_MASK_CAPTURE_THREAD); } diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index c4bdbb1c..5ebd4944 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -40,8 +40,8 @@ class CaptureThread { public: CaptureThread( std::unique_ptr writer, - size_t write_size_log2, - size_t buffer_count_log2 + size_t write_size, + size_t buffer_count ); ~CaptureThread(); diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 3f905f06..8db26f2b 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -139,13 +139,13 @@ RecordView::RecordView( const Rect parent_rect, std::string filename_stem_pattern, const FileType file_type, - const size_t buffer_size_k, - const size_t buffer_count_k + const size_t write_size, + const size_t buffer_count ) : View { parent_rect }, filename_stem_pattern { filename_stem_pattern }, file_type { file_type }, - buffer_size_k { buffer_size_k }, - buffer_count_k { buffer_count_k } + write_size { write_size }, + buffer_count { buffer_count } { add_children({ { &button_record, @@ -222,7 +222,7 @@ void RecordView::start() { button_record.set_bitmap(&bitmap_stop); capture_thread = std::make_unique( std::move(writer), - buffer_size_k, buffer_count_k + write_size, buffer_count ); } } diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 0c8c24bb..88d77fd2 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -46,8 +46,8 @@ public: const Rect parent_rect, std::string filename_stem_pattern, FileType file_type, - const size_t buffer_size_k, - const size_t buffer_count_k + const size_t write_size, + const size_t buffer_count ); ~RecordView(); @@ -73,8 +73,8 @@ private: const std::string filename_stem_pattern; const FileType file_type; - const size_t buffer_size_k; - const size_t buffer_count_k; + const size_t write_size; + const size_t buffer_count; size_t sampling_rate { 0 }; SignalToken signal_token_tick_second; diff --git a/firmware/baseband/Makefile b/firmware/baseband/Makefile index 5881ff66..dda8f28c 100755 --- a/firmware/baseband/Makefile +++ b/firmware/baseband/Makefile @@ -146,6 +146,7 @@ CPPSRC = main.cpp \ proc_tpms.cpp \ proc_ert.cpp \ proc_capture.cpp \ + stream_input.cpp \ dsp_squelch.cpp \ clock_recovery.cpp \ packet_builder.cpp \ diff --git a/firmware/baseband/stream_input.cpp b/firmware/baseband/stream_input.cpp new file mode 100644 index 00000000..f383be9c --- /dev/null +++ b/firmware/baseband/stream_input.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 Jared Boone, ShareBrained Technology, 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. + */ + +#include "stream_input.hpp" + +#include "lpc43xx_cpp.hpp" +using namespace lpc43xx; + +StreamInput::StreamInput(CaptureConfig* const config) : + fifo_buffers_empty { buffers_empty.data(), buffer_count_max_log2 }, + fifo_buffers_full { buffers_full.data(), buffer_count_max_log2 }, + config { config }, + data { std::make_unique(config->write_size * config->buffer_count) } +{ + config->fifo_buffers_empty = &fifo_buffers_empty; + config->fifo_buffers_full = &fifo_buffers_full; + + for(size_t i=0; ibuffer_count; i++) { + buffers[i] = { &(data.get()[i * config->write_size]), config->write_size }; + fifo_buffers_empty.in(&buffers[i]); + } +} + +size_t StreamInput::write(const void* const data, const size_t length) { + const uint8_t* p = static_cast(data); + size_t written = 0; + + while( written < length ) { + if( !active_buffer ) { + // We need an empty buffer... + if( !fifo_buffers_empty.out(active_buffer) ) { + // ...but none are available. Samples were dropped. + break; + } + } + + const auto remaining = length - written; + written += active_buffer->write(&p[written], remaining); + + if( active_buffer->is_full() ) { + if( !fifo_buffers_full.in(active_buffer) ) { + // FIFO is fuil of buffers, there's no place for this one. + // Bail out of the loop, and try submitting the buffer in the + // next pass. + // This should never happen if the number of buffers is less + // than the capacity of the FIFO. + break; + } + active_buffer = nullptr; + creg::m4txevent::assert(); + } + } + + config->baseband_bytes_received += length; + config->baseband_bytes_dropped += (length - written); + + return written; +} diff --git a/firmware/baseband/stream_input.hpp b/firmware/baseband/stream_input.hpp index cb4bbe4e..ce4a29a4 100644 --- a/firmware/baseband/stream_input.hpp +++ b/firmware/baseband/stream_input.hpp @@ -25,46 +25,29 @@ #include "message.hpp" #include "fifo.hpp" -#include "lpc43xx_cpp.hpp" -using namespace lpc43xx; - #include #include +#include #include class StreamInput { public: - StreamInput(CaptureConfig* const config) : - config { config }, - K { config->write_size_log2 + config->buffer_count_log2 }, - event_bytes_mask { (1UL << config->write_size_log2) - 1 }, - data { std::make_unique(1UL << K) }, - fifo { data.get(), K } - { - config->fifo = &fifo; - } + StreamInput(CaptureConfig* const config); - size_t write(const void* const data, const size_t length) { - const auto written = fifo.in(reinterpret_cast(data), length); - - const auto last_bytes_written = bytes_written; - bytes_written += written; - if( (bytes_written & event_bytes_mask) < (last_bytes_written & event_bytes_mask) ) { - creg::m4txevent::assert(); - } - config->baseband_bytes_received += length; - config->baseband_bytes_dropped = config->baseband_bytes_received - bytes_written; - - return written; - } + size_t write(const void* const data, const size_t length); private: - CaptureConfig* const config; - const size_t K; - const uint64_t event_bytes_mask; - uint64_t bytes_written = 0; + static constexpr size_t buffer_count_max_log2 = 3; + static constexpr size_t buffer_count_max = 1U << buffer_count_max_log2; + + FIFO fifo_buffers_empty; + FIFO fifo_buffers_full; + std::array buffers; + std::array buffers_empty; + std::array buffers_full; + StreamBuffer* active_buffer { nullptr }; + CaptureConfig* const config { nullptr }; std::unique_ptr data; - FIFO fifo; }; #endif/*__STREAM_INPUT_H__*/ diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index f1b20a4e..bc94fe12 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -411,21 +412,63 @@ public: const iir_biquad_config_t audio_hpf_config; }; +// TODO: Put this somewhere else, or at least the implementation part. +class StreamBuffer { + uint8_t* data_; + size_t used_; + size_t capacity_; + +public: + constexpr StreamBuffer( + void* const data = nullptr, + const size_t capacity = 0 + ) : data_ { static_cast(data) }, + used_ { 0 }, + capacity_ { capacity } + { + } + + size_t write(const void* p, const size_t count) { + const auto copy_size = std::min(capacity_ - used_, count); + memcpy(&data_[used_], p, copy_size); + used_ += copy_size; + return copy_size; + } + + bool is_full() const { + return used_ >= capacity_; + } + + const void* data() const { + return data_; + } + + size_t size() const { + return used_; + } + + void empty() { + used_ = 0; + } +}; + struct CaptureConfig { - const size_t write_size_log2; - const size_t buffer_count_log2; + const size_t write_size; + const size_t buffer_count; uint64_t baseband_bytes_received; uint64_t baseband_bytes_dropped; - FIFO* fifo; + FIFO* fifo_buffers_empty; + FIFO* fifo_buffers_full; constexpr CaptureConfig( - const size_t write_size_log2, - const size_t buffer_count_log2 - ) : write_size_log2 { write_size_log2 }, - buffer_count_log2 { buffer_count_log2 }, + const size_t write_size, + const size_t buffer_count + ) : write_size { write_size }, + buffer_count { buffer_count }, baseband_bytes_received { 0 }, baseband_bytes_dropped { 0 }, - fifo { nullptr } + fifo_buffers_empty { nullptr }, + fifo_buffers_full { nullptr } { } From c48a88539a840840111ad2888f0fc97845b73140 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 10 May 2016 14:39:24 -0700 Subject: [PATCH 009/165] Check capture FIFO before waking M0 capture thread. --- firmware/application/capture_thread.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index 7d1eb557..64ad0753 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -103,7 +103,9 @@ void CaptureThread::check_fifo_isr() { // flags from the baseband core. const auto fifo = StreamOutput::fifo_buffers_full; if( fifo ) { - chEvtSignalI(thread, EVT_MASK_CAPTURE_THREAD); + if( !fifo->is_empty() ) { + chEvtSignalI(thread, EVT_MASK_CAPTURE_THREAD); + } } } From f157c13442db9e11cd2936f13ac46300caf27baa Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 May 2016 10:58:57 -0700 Subject: [PATCH 010/165] Implement std::filesystem::space(). --- firmware/application/file.cpp | 18 ++++++++++++++++++ firmware/application/file.hpp | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index 18e75005..7c73a729 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -164,5 +164,23 @@ bool is_regular_file(const file_status s) { return !(s & AM_DIR); } +space_info space(const path& p) { + DWORD free_clusters { 0 }; + FATFS* fs; + if( f_getfree(p.c_str(), &free_clusters, &fs) == FR_OK ) { +#if _MAX_SS != _MIN_SS + static_assert(false, "FatFs not configured for fixed sector size"); +#else + return { + (fs->n_fatent - 2) * fs->csize * _MIN_SS, + free_clusters * fs->csize * _MIN_SS, + free_clusters * fs->csize * _MIN_SS, + }; +#endif + } else { + return { 0, 0, 0 }; + } +} + } /* namespace filesystem */ } /* namespace std */ diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index 6be0f9dd..fde40db2 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -25,6 +25,7 @@ #include "ff.h" #include +#include #include #include #include @@ -75,8 +76,17 @@ std::string next_filename_stem_matching_pattern(const std::string& filename_stem namespace std { namespace filesystem { +using path = std::string; using file_status = BYTE; +struct space_info { + static_assert(sizeof(std::uintmax_t) >= 8, "std::uintmax_t too small ( Date: Wed, 11 May 2016 11:22:57 -0700 Subject: [PATCH 011/165] Display remaining capture time on SD card. --- firmware/application/ui_record_view.cpp | 6 ++++++ firmware/application/ui_record_view.hpp | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 8db26f2b..96a368d6 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -151,6 +151,7 @@ RecordView::RecordView( &button_record, &text_record_filename, &text_record_dropped, + &text_time_recorded, } }); button_record.on_select = [this](ImageButton&) { @@ -245,6 +246,11 @@ void RecordView::on_tick_second() { const auto dropped_percent = std::min(99U, capture_thread->state().dropped_percent()); const auto s = to_string_dec_uint(dropped_percent, 2, ' ') + "\%"; text_record_dropped.set(s); + + const auto space_info = std::filesystem::space(""); + const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate * 4); + const uint32_t free_seconds = space_info.free / bytes_per_second; + text_time_recorded.set(to_string_dec_uint(free_seconds, 6, ' ') + "s"); } } diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 88d77fd2..3c0901c6 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -95,6 +95,11 @@ private: "", }; + Text text_time_recorded { + { 23 * 8, 0 * 16, 7 * 8, 16 }, + "", + }; + std::unique_ptr capture_thread; }; From 7d3e697ea80550f85dfab1830520e939c8759de4 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 May 2016 11:50:40 -0700 Subject: [PATCH 012/165] Rename SD record variables: "free"/"recorded" -> "available" --- firmware/application/ui_record_view.cpp | 6 +++--- firmware/application/ui_record_view.hpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 96a368d6..1e7e8c9e 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -151,7 +151,7 @@ RecordView::RecordView( &button_record, &text_record_filename, &text_record_dropped, - &text_time_recorded, + &text_time_available, } }); button_record.on_select = [this](ImageButton&) { @@ -249,8 +249,8 @@ void RecordView::on_tick_second() { const auto space_info = std::filesystem::space(""); const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate * 4); - const uint32_t free_seconds = space_info.free / bytes_per_second; - text_time_recorded.set(to_string_dec_uint(free_seconds, 6, ' ') + "s"); + const uint32_t available_seconds = space_info.free / bytes_per_second; + text_time_available.set(to_string_dec_uint(available_seconds, 6, ' ') + "s"); } } diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 3c0901c6..4b646acf 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -95,7 +95,7 @@ private: "", }; - Text text_time_recorded { + Text text_time_available { { 23 * 8, 0 * 16, 7 * 8, 16 }, "", }; From 7fd508dfbee2deb2f1b2a7a1df3cbec746420b82 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 May 2016 12:02:39 -0700 Subject: [PATCH 013/165] Format remaining time on SD card as "HHH:MM:SS". --- firmware/application/ui_record_view.cpp | 10 +++++++++- firmware/application/ui_record_view.hpp | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 1e7e8c9e..6cf4c7a3 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -250,7 +250,15 @@ void RecordView::on_tick_second() { const auto space_info = std::filesystem::space(""); const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate * 4); const uint32_t available_seconds = space_info.free / bytes_per_second; - text_time_available.set(to_string_dec_uint(available_seconds, 6, ' ') + "s"); + const uint32_t seconds = available_seconds % 60; + const uint32_t available_minutes = available_seconds / 60; + const uint32_t minutes = available_minutes % 60; + const uint32_t hours = available_minutes / 60; + const std::string available_time = + to_string_dec_uint(hours, 3, ' ') + ":" + + to_string_dec_uint(minutes, 2, ' ') + ":" + + to_string_dec_uint(seconds, 2, '0'); + text_time_available.set(available_time); } } diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 4b646acf..5cbaabb4 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -96,7 +96,7 @@ private: }; Text text_time_available { - { 23 * 8, 0 * 16, 7 * 8, 16 }, + { 21 * 8, 0 * 16, 9 * 8, 16 }, "", }; From 46d4c919fb5c5bbc0af7969c46e8ceaf56e56a42 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 May 2016 12:07:58 -0700 Subject: [PATCH 014/165] Show SD card capture time remaining even when not capturing. --- firmware/application/ui_record_view.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 6cf4c7a3..6d423184 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -246,7 +246,9 @@ void RecordView::on_tick_second() { const auto dropped_percent = std::min(99U, capture_thread->state().dropped_percent()); const auto s = to_string_dec_uint(dropped_percent, 2, ' ') + "\%"; text_record_dropped.set(s); + } + if( sampling_rate ) { const auto space_info = std::filesystem::space(""); const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate * 4); const uint32_t available_seconds = space_info.free / bytes_per_second; From e298e1ec5ad4d42fe15bfea48a90b19787df9686 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 May 2016 12:34:09 -0700 Subject: [PATCH 015/165] Fix SD capture remaining time formatting -- zero pad minutes. --- firmware/application/ui_record_view.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 6d423184..5e813a90 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -258,7 +258,7 @@ void RecordView::on_tick_second() { const uint32_t hours = available_minutes / 60; const std::string available_time = to_string_dec_uint(hours, 3, ' ') + ":" + - to_string_dec_uint(minutes, 2, ' ') + ":" + + to_string_dec_uint(minutes, 2, '0') + ":" + to_string_dec_uint(seconds, 2, '0'); text_time_available.set(available_time); } From 7d4dd0341853c704efdf280b520743c8c6e2c87d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 May 2016 22:53:09 -0700 Subject: [PATCH 016/165] Wrap message handler registrations in class to subscribe/unsubscribe automatically. --- firmware/application/ais_app.cpp | 14 ------ firmware/application/ais_app.hpp | 13 +++++ firmware/application/ert_app.cpp | 12 ----- firmware/application/ert_app.hpp | 11 +++++ firmware/application/event_m0.hpp | 19 ++++++++ firmware/application/main.cpp | 47 +++++++++++-------- firmware/application/tpms_app.cpp | 12 ----- firmware/application/tpms_app.hpp | 11 +++++ firmware/application/ui_audio.cpp | 14 ------ firmware/application/ui_audio.hpp | 12 +++-- .../application/ui_baseband_stats_view.cpp | 15 ------ .../application/ui_baseband_stats_view.hpp | 13 +++-- firmware/application/ui_channel.cpp | 14 ------ firmware/application/ui_channel.hpp | 12 +++-- firmware/application/ui_rssi.cpp | 14 ------ firmware/application/ui_rssi.hpp | 12 +++-- firmware/application/ui_spectrum.cpp | 22 --------- firmware/application/ui_spectrum.hpp | 21 +++++++++ 18 files changed, 139 insertions(+), 149 deletions(-) diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index a6508c91..964ddf8d 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -21,8 +21,6 @@ #include "ais_app.hpp" -#include "event_m0.hpp" - #include "string_format.hpp" #include "baseband_api.hpp" @@ -305,16 +303,6 @@ AISAppView::AISAppView(NavigationView&) { recent_entry_detail_view.hidden(true); - EventDispatcher::message_map().register_handler(Message::ID::AISPacket, - [this](Message* const p) { - const auto message = static_cast(p); - const ais::Packet packet { message->packet }; - if( packet.is_valid() ) { - this->on_packet(packet); - } - } - ); - target_frequency_ = initial_target_frequency; radio::enable({ @@ -350,8 +338,6 @@ AISAppView::AISAppView(NavigationView&) { AISAppView::~AISAppView() { baseband::stop(); radio::disable(); - - EventDispatcher::message_map().unregister_handler(Message::ID::AISPacket); } void AISAppView::focus() { diff --git a/firmware/application/ais_app.hpp b/firmware/application/ais_app.hpp index f0f81c91..a166f47d 100644 --- a/firmware/application/ais_app.hpp +++ b/firmware/application/ais_app.hpp @@ -25,6 +25,8 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" +#include "event_m0.hpp" + #include "log_file.hpp" #include "ais_packet.hpp" @@ -173,6 +175,17 @@ private: } }; + MessageHandlerRegistration message_handler_packet { + Message::ID::AISPacket, + [this](Message* const p) { + const auto message = static_cast(p); + const ais::Packet packet { message->packet }; + if( packet.is_valid() ) { + this->on_packet(packet); + } + } + }; + uint32_t target_frequency_ = initial_target_frequency; void on_packet(const ais::Packet& packet); diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index bbdf5848..86b93339 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -21,8 +21,6 @@ #include "ert_app.hpp" -#include "event_m0.hpp" - #include "baseband_api.hpp" #include "manchester.hpp" @@ -135,14 +133,6 @@ ERTAppView::ERTAppView(NavigationView&) { &recent_entries_view, } }); - EventDispatcher::message_map().register_handler(Message::ID::ERTPacket, - [this](Message* const p) { - const auto message = static_cast(p); - const ert::Packet packet { message->type, message->packet }; - this->on_packet(packet); - } - ); - radio::enable({ initial_target_frequency, sampling_rate, @@ -164,8 +154,6 @@ ERTAppView::ERTAppView(NavigationView&) { ERTAppView::~ERTAppView() { baseband::stop(); radio::disable(); - - EventDispatcher::message_map().unregister_handler(Message::ID::ERTPacket); } void ERTAppView::focus() { diff --git a/firmware/application/ert_app.hpp b/firmware/application/ert_app.hpp index e280f379..403d9b63 100644 --- a/firmware/application/ert_app.hpp +++ b/firmware/application/ert_app.hpp @@ -24,6 +24,8 @@ #include "ui_navigation.hpp" +#include "event_m0.hpp" + #include "log_file.hpp" #include "ert_packet.hpp" @@ -124,6 +126,15 @@ private: ERTRecentEntriesView recent_entries_view { recent }; + MessageHandlerRegistration message_handler_packet { + Message::ID::ERTPacket, + [this](Message* const p) { + const auto message = static_cast(p); + const ert::Packet packet { message->type, message->packet }; + this->on_packet(packet); + } + }; + void on_packet(const ert::Packet& packet); void on_show_list(); }; diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index f793eaf7..704e774e 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -117,4 +117,23 @@ private: void init_message_queues(); }; +class MessageHandlerRegistration { +public: + template + MessageHandlerRegistration( + const Message::ID message_id, + Callback callback + ) : message_id { message_id } + { + EventDispatcher::message_map().register_handler(message_id, callback); + } + + ~MessageHandlerRegistration() { + EventDispatcher::message_map().unregister_handler(message_id); + } + +private: + const Message::ID message_id; +}; + #endif/*__EVENT_M0_H__*/ diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index bc37759f..63f9a822 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -51,6 +51,32 @@ #include +static void event_loop() { + ui::Context context; + ui::SystemView system_view { + context, + portapack::display.screen_rect() + }; + ui::Painter painter; + + EventDispatcher event_dispatcher { &system_view, painter, context }; + + MessageHandlerRegistration message_handler_shutdown { + Message::ID::Shutdown, + [&event_dispatcher](const Message* const) { + event_dispatcher.request_stop(); + } + }; + MessageHandlerRegistration message_handler_display_sleep { + Message::ID::DisplaySleep, + [&event_dispatcher](const Message* const) { + event_dispatcher.set_display_sleep(true); + } + }; + + event_dispatcher.run(); +} + int main(void) { portapack::init(); @@ -63,32 +89,13 @@ int main(void) { sdcStart(&SDCD1, nullptr); - ui::Context context; - ui::SystemView system_view { - context, - portapack::display.screen_rect() - }; - ui::Painter painter; - EventDispatcher event_dispatcher { &system_view, painter, context }; - - EventDispatcher::message_map().register_handler(Message::ID::Shutdown, - [&event_dispatcher](const Message* const) { - event_dispatcher.request_stop(); - } - ); - EventDispatcher::message_map().register_handler(Message::ID::DisplaySleep, - [&event_dispatcher](const Message* const) { - event_dispatcher.set_display_sleep(true); - } - ); - m4_init(portapack::spi_flash::baseband, portapack::memory::map::m4_code); controls_init(); lcd_frame_sync_configure(); rtc_interrupt_enable(); - event_dispatcher.run(); + event_loop(); sdcDisconnect(&SDCD1); sdcStop(&SDCD1); diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index abe27450..46f04537 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -21,8 +21,6 @@ #include "tpms_app.hpp" -#include "event_m0.hpp" - #include "baseband_api.hpp" #include "string_format.hpp" @@ -152,14 +150,6 @@ TPMSAppView::TPMSAppView(NavigationView&) { &recent_entries_view, } }); - EventDispatcher::message_map().register_handler(Message::ID::TPMSPacket, - [this](Message* const p) { - const auto message = static_cast(p); - const tpms::Packet packet { message->packet }; - this->on_packet(message->signal_type, packet); - } - ); - radio::enable({ tuning_frequency(), sampling_rate, @@ -181,8 +171,6 @@ TPMSAppView::TPMSAppView(NavigationView&) { TPMSAppView::~TPMSAppView() { baseband::stop(); radio::disable(); - - EventDispatcher::message_map().unregister_handler(Message::ID::TPMSPacket); } void TPMSAppView::focus() { diff --git a/firmware/application/tpms_app.hpp b/firmware/application/tpms_app.hpp index 24516908..ea0e9b39 100644 --- a/firmware/application/tpms_app.hpp +++ b/firmware/application/tpms_app.hpp @@ -25,6 +25,8 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" +#include "event_m0.hpp" + #include "log_file.hpp" #include "recent_entries.hpp" @@ -102,6 +104,15 @@ private: static constexpr uint32_t sampling_rate = 2457600; static constexpr uint32_t baseband_bandwidth = 1750000; + MessageHandlerRegistration message_handler_packet { + Message::ID::TPMSPacket, + [this](Message* const p) { + const auto message = static_cast(p); + const tpms::Packet packet { message->packet }; + this->on_packet(message->signal_type, packet); + } + }; + TPMSRecentEntries recent; std::unique_ptr logger; diff --git a/firmware/application/ui_audio.cpp b/firmware/application/ui_audio.cpp index 65fd3832..389a65e1 100644 --- a/firmware/application/ui_audio.cpp +++ b/firmware/application/ui_audio.cpp @@ -21,26 +21,12 @@ #include "ui_audio.hpp" -#include "event_m0.hpp" - #include "utility.hpp" #include namespace ui { -void Audio::on_show() { - EventDispatcher::message_map().register_handler(Message::ID::AudioStatistics, - [this](const Message* const p) { - this->on_statistics_update(static_cast(p)->statistics); - } - ); -} - -void Audio::on_hide() { - EventDispatcher::message_map().unregister_handler(Message::ID::AudioStatistics); -} - void Audio::paint(Painter& painter) { const auto r = screen_rect(); diff --git a/firmware/application/ui_audio.hpp b/firmware/application/ui_audio.hpp index 00d7f908..e1ae5ad7 100644 --- a/firmware/application/ui_audio.hpp +++ b/firmware/application/ui_audio.hpp @@ -26,6 +26,8 @@ #include "ui_widget.hpp" #include "ui_painter.hpp" +#include "event_m0.hpp" + #include "message.hpp" #include @@ -42,15 +44,19 @@ public: { } - void on_show() override; - void on_hide() override; - void paint(Painter& painter) override; private: int32_t rms_db_; int32_t max_db_; + MessageHandlerRegistration message_handler_statistics { + Message::ID::AudioStatistics, + [this](const Message* const p) { + this->on_statistics_update(static_cast(p)->statistics); + } + }; + void on_statistics_update(const AudioStatistics& statistics); }; diff --git a/firmware/application/ui_baseband_stats_view.cpp b/firmware/application/ui_baseband_stats_view.cpp index 0d576e81..44774465 100644 --- a/firmware/application/ui_baseband_stats_view.cpp +++ b/firmware/application/ui_baseband_stats_view.cpp @@ -21,8 +21,6 @@ #include "ui_baseband_stats_view.hpp" -#include "event_m0.hpp" - #include #include @@ -41,19 +39,6 @@ BasebandStatsView::BasebandStatsView() { } }); } -void BasebandStatsView::on_show() { - EventDispatcher::message_map().register_handler(Message::ID::BasebandStatistics, - [this](const Message* const p) { - this->on_statistics_update(static_cast(p)->statistics); - } - ); -} - -void BasebandStatsView::on_hide() { - EventDispatcher::message_map().unregister_handler(Message::ID::BasebandStatistics); -} - - static std::string ticks_to_percent_string(const uint32_t ticks) { constexpr size_t decimal_digits = 1; constexpr size_t decimal_factor = decimal_digits * 10; diff --git a/firmware/application/ui_baseband_stats_view.hpp b/firmware/application/ui_baseband_stats_view.hpp index 70026618..2c07c20b 100644 --- a/firmware/application/ui_baseband_stats_view.hpp +++ b/firmware/application/ui_baseband_stats_view.hpp @@ -23,6 +23,9 @@ #define __UI_BASEBAND_STATS_VIEW_H__ #include "ui_widget.hpp" + +#include "event_m0.hpp" + #include "message.hpp" namespace ui { @@ -31,15 +34,19 @@ class BasebandStatsView : public View { public: BasebandStatsView(); - void on_show() override; - void on_hide() override; - private: Text text_stats { { 0 * 8, 0, (4 * 4 + 3) * 8, 1 * 16 }, "", }; + MessageHandlerRegistration message_handler_stats { + Message::ID::BasebandStatistics, + [this](const Message* const p) { + this->on_statistics_update(static_cast(p)->statistics); + } + }; + void on_statistics_update(const BasebandStatistics& statistics); }; diff --git a/firmware/application/ui_channel.cpp b/firmware/application/ui_channel.cpp index 62f1b49a..3d21e535 100644 --- a/firmware/application/ui_channel.cpp +++ b/firmware/application/ui_channel.cpp @@ -21,26 +21,12 @@ #include "ui_channel.hpp" -#include "event_m0.hpp" - #include "utility.hpp" #include namespace ui { -void Channel::on_show() { - EventDispatcher::message_map().register_handler(Message::ID::ChannelStatistics, - [this](const Message* const p) { - this->on_statistics_update(static_cast(p)->statistics); - } - ); -} - -void Channel::on_hide() { - EventDispatcher::message_map().unregister_handler(Message::ID::ChannelStatistics); -} - void Channel::paint(Painter& painter) { const auto r = screen_rect(); diff --git a/firmware/application/ui_channel.hpp b/firmware/application/ui_channel.hpp index 3b7f4969..bf8e832e 100644 --- a/firmware/application/ui_channel.hpp +++ b/firmware/application/ui_channel.hpp @@ -26,6 +26,8 @@ #include "ui_widget.hpp" #include "ui_painter.hpp" +#include "event_m0.hpp" + #include "message.hpp" #include @@ -41,14 +43,18 @@ public: { } - void on_show() override; - void on_hide() override; - void paint(Painter& painter) override; private: int32_t max_db_; + MessageHandlerRegistration message_handler_stats { + Message::ID::ChannelStatistics, + [this](const Message* const p) { + this->on_statistics_update(static_cast(p)->statistics); + } + }; + void on_statistics_update(const ChannelStatistics& statistics); }; diff --git a/firmware/application/ui_rssi.cpp b/firmware/application/ui_rssi.cpp index a5646863..ab506906 100644 --- a/firmware/application/ui_rssi.cpp +++ b/firmware/application/ui_rssi.cpp @@ -21,26 +21,12 @@ #include "ui_rssi.hpp" -#include "event_m0.hpp" - #include "utility.hpp" #include namespace ui { -void RSSI::on_show() { - EventDispatcher::message_map().register_handler(Message::ID::RSSIStatistics, - [this](const Message* const p) { - this->on_statistics_update(static_cast(p)->statistics); - } - ); -} - -void RSSI::on_hide() { - EventDispatcher::message_map().unregister_handler(Message::ID::RSSIStatistics); -} - void RSSI::paint(Painter& painter) { const auto r = screen_rect(); diff --git a/firmware/application/ui_rssi.hpp b/firmware/application/ui_rssi.hpp index 5c457039..08eeadcb 100644 --- a/firmware/application/ui_rssi.hpp +++ b/firmware/application/ui_rssi.hpp @@ -26,6 +26,8 @@ #include "ui_widget.hpp" #include "ui_painter.hpp" +#include "event_m0.hpp" + #include "message.hpp" #include @@ -43,9 +45,6 @@ public: { } - void on_show() override; - void on_hide() override; - void paint(Painter& painter) override; private: @@ -53,6 +52,13 @@ private: int32_t avg_; int32_t max_; + MessageHandlerRegistration message_handler_stats { + Message::ID::RSSIStatistics, + [this](const Message* const p) { + this->on_statistics_update(static_cast(p)->statistics); + } + }; + void on_statistics_update(const RSSIStatistics& statistics); }; diff --git a/firmware/application/ui_spectrum.cpp b/firmware/application/ui_spectrum.cpp index a3b7c896..448e0766 100644 --- a/firmware/application/ui_spectrum.cpp +++ b/firmware/application/ui_spectrum.cpp @@ -21,8 +21,6 @@ #include "ui_spectrum.hpp" -#include "event_m0.hpp" - #include "spectrum_color_lut.hpp" #include "portapack.hpp" @@ -236,31 +234,11 @@ WaterfallWidget::WaterfallWidget() { } void WaterfallWidget::on_show() { - EventDispatcher::message_map().register_handler(Message::ID::ChannelSpectrumConfig, - [this](const Message* const p) { - const auto message = *reinterpret_cast(p); - this->fifo = message.fifo; - } - ); - EventDispatcher::message_map().register_handler(Message::ID::DisplayFrameSync, - [this](const Message* const) { - if( this->fifo ) { - ChannelSpectrum channel_spectrum; - while( fifo->out(channel_spectrum) ) { - this->on_channel_spectrum(channel_spectrum); - } - } - } - ); - baseband::spectrum_streaming_start(); } void WaterfallWidget::on_hide() { baseband::spectrum_streaming_stop(); - - EventDispatcher::message_map().unregister_handler(Message::ID::DisplayFrameSync); - EventDispatcher::message_map().unregister_handler(Message::ID::ChannelSpectrumConfig); } void WaterfallWidget::set_parent_rect(const Rect new_parent_rect) { diff --git a/firmware/application/ui_spectrum.hpp b/firmware/application/ui_spectrum.hpp index 8b0381f4..70fe83d5 100644 --- a/firmware/application/ui_spectrum.hpp +++ b/firmware/application/ui_spectrum.hpp @@ -25,6 +25,8 @@ #include "ui.hpp" #include "ui_widget.hpp" +#include "event_m0.hpp" + #include "message.hpp" #include @@ -86,6 +88,25 @@ private: FrequencyScale frequency_scale; ChannelSpectrumFIFO* fifo { nullptr }; + MessageHandlerRegistration message_handler_spectrum_config { + Message::ID::ChannelSpectrumConfig, + [this](const Message* const p) { + const auto message = *reinterpret_cast(p); + this->fifo = message.fifo; + } + }; + MessageHandlerRegistration message_handler_frame_sync { + Message::ID::DisplayFrameSync, + [this](const Message* const) { + if( this->fifo ) { + ChannelSpectrum channel_spectrum; + while( fifo->out(channel_spectrum) ) { + this->on_channel_spectrum(channel_spectrum); + } + } + } + }; + void on_channel_spectrum(const ChannelSpectrum& spectrum); }; From d64344a84f42054e9eb683824fd365e8a9320387 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 15:24:08 -0700 Subject: [PATCH 017/165] Un-template MessageHandlerRegistration, move code to .cpp. --- firmware/application/event_m0.cpp | 12 ++++++++++++ firmware/application/event_m0.hpp | 14 ++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 388695ef..47b0cd23 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -257,3 +257,15 @@ void EventDispatcher::init_message_queues() { shared_memory.application_queue_data, SharedMemory::application_queue_k ); } + +MessageHandlerRegistration::MessageHandlerRegistration( + const Message::ID message_id, + MessageHandlerMap::MessageHandler&& callback +) : message_id { message_id } +{ + EventDispatcher::message_map().register_handler(message_id, std::move(callback)); +} + +MessageHandlerRegistration::~MessageHandlerRegistration() { + EventDispatcher::message_map().unregister_handler(message_id); +} diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 704e774e..947f51ee 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -119,19 +119,13 @@ private: class MessageHandlerRegistration { public: - template MessageHandlerRegistration( const Message::ID message_id, - Callback callback - ) : message_id { message_id } - { - EventDispatcher::message_map().register_handler(message_id, callback); - } - - ~MessageHandlerRegistration() { - EventDispatcher::message_map().unregister_handler(message_id); - } + MessageHandlerMap::MessageHandler&& callback + ); + ~MessageHandlerRegistration(); + private: const Message::ID message_id; }; From 479a96fc22a9ea0a7df4c20724418b5c63c820f6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 15:52:18 -0700 Subject: [PATCH 018/165] Move Painter into EventDispatcher. --- firmware/application/event_m0.cpp | 3 +-- firmware/application/event_m0.hpp | 3 +-- firmware/application/main.cpp | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 47b0cd23..f0f0bdb4 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -62,10 +62,9 @@ Thread* EventDispatcher::thread_event_loop = nullptr; EventDispatcher::EventDispatcher( ui::Widget* const top_widget, - ui::Painter& painter, ui::Context& context ) : top_widget { top_widget }, - painter(painter), + painter { }, context(context) { init_message_queues(); diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 947f51ee..6c716488 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -50,7 +50,6 @@ class EventDispatcher { public: EventDispatcher( ui::Widget* const top_widget, - ui::Painter& painter, ui::Context& context ); @@ -87,7 +86,7 @@ private: touch::Manager touch_manager; ui::Widget* const top_widget; - ui::Painter& painter; + ui::Painter painter; ui::Context& context; uint32_t encoder_last = 0; bool is_running = true; diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 63f9a822..0475073c 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -57,9 +57,8 @@ static void event_loop() { context, portapack::display.screen_rect() }; - ui::Painter painter; - EventDispatcher event_dispatcher { &system_view, painter, context }; + EventDispatcher event_dispatcher { &system_view, context }; MessageHandlerRegistration message_handler_shutdown { Message::ID::Shutdown, From 4567db2fdb279026545195748964eb9f00fcef46 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 18:19:28 -0700 Subject: [PATCH 019/165] Add std::filesystem::filesystem_error object. Not a standards-compliant implementation, but has the same vague shape, so should be easier to port later(?). --- firmware/application/file.cpp | 26 ++++++++++++++++++++++++++ firmware/application/file.hpp | 10 ++++++++++ 2 files changed, 36 insertions(+) diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index 7c73a729..7a815fc5 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -140,6 +140,32 @@ std::string next_filename_stem_matching_pattern(const std::string& filename_stem namespace std { namespace filesystem { +std::string filesystem_error::what() const { + switch(err) { + case FR_OK: return ""; + case FR_DISK_ERR: return "disk error"; + case FR_INT_ERR: return "insanity detected"; + case FR_NOT_READY: return "not ready"; + case FR_NO_FILE: return "no file"; + case FR_NO_PATH: return "no path"; + case FR_INVALID_NAME: return "invalid name"; + case FR_DENIED: return "denied"; + case FR_EXIST: return "exists"; + case FR_INVALID_OBJECT: return "invalid object"; + case FR_WRITE_PROTECTED: return "write protected"; + case FR_INVALID_DRIVE: return "invalid drive"; + case FR_NOT_ENABLED: return "not enabled"; + case FR_NO_FILESYSTEM: return "no filesystem"; + case FR_MKFS_ABORTED: return "mkfs aborted"; + case FR_TIMEOUT: return "timeout"; + case FR_LOCKED: return "locked"; + case FR_NOT_ENOUGH_CORE: return "not enough core"; + case FR_TOO_MANY_OPEN_FILES: return "too many open files"; + case FR_INVALID_PARAMETER: return "invalid parameter"; + default: return "unknown"; + } +} + directory_iterator::directory_iterator( const char* path, const char* wild diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index fde40db2..56f9525d 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -76,6 +76,16 @@ std::string next_filename_stem_matching_pattern(const std::string& filename_stem namespace std { namespace filesystem { +struct filesystem_error { + const BYTE err; + + operator bool() const { + return err != FR_OK; + } + + std::string what() const; +}; + using path = std::string; using file_status = BYTE; From 0f1ae96ba4d737a578d0ded1188520d39c5e4d86 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 21:44:37 -0700 Subject: [PATCH 020/165] Move File definition below std::filesystem. --- firmware/application/file.hpp | 80 +++++++++++++++++------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index 56f9525d..789d2310 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -31,46 +31,6 @@ #include #include -class File { -public: - enum openmode { - app = 0x100, - binary = 0x200, - in = FA_READ, - out = FA_WRITE, - trunc = FA_CREATE_ALWAYS, - ate = FA_OPEN_ALWAYS, - }; - - File(const std::string& filename, openmode mode); - ~File(); - - bool is_open() const { - return f_error(&f) == 0; - } - - bool read(void* const data, const size_t bytes_to_read); - bool write(const void* const data, const size_t bytes_to_write); - - uint64_t seek(const uint64_t new_position); - - template - bool write(const std::array& data) { - return write(data.data(), N); - } - - bool puts(const std::string& string); - - bool sync(); - -private: - FIL f; -}; - -inline constexpr File::openmode operator|(File::openmode a, File::openmode b) { - return File::openmode(static_cast(a) | static_cast(b)); -} - std::string next_filename_stem_matching_pattern(const std::string& filename_stem_pattern); namespace std { @@ -151,4 +111,44 @@ space_info space(const path& p); } /* namespace filesystem */ } /* namespace std */ +class File { +public: + enum openmode { + app = 0x100, + binary = 0x200, + in = FA_READ, + out = FA_WRITE, + trunc = FA_CREATE_ALWAYS, + ate = FA_OPEN_ALWAYS, + }; + + File(const std::string& filename, openmode mode); + ~File(); + + bool is_open() const { + return f_error(&f) == 0; + } + + bool read(void* const data, const size_t bytes_to_read); + bool write(const void* const data, const size_t bytes_to_write); + + uint64_t seek(const uint64_t new_position); + + template + bool write(const std::array& data) { + return write(data.data(), N); + } + + bool puts(const std::string& string); + + bool sync(); + +private: + FIL f; +}; + +inline constexpr File::openmode operator|(File::openmode a, File::openmode b) { + return File::openmode(static_cast(a) | static_cast(b)); +} + #endif/*__FILE_H__*/ From b21758781c983e4ea2c4526257e38705f712fcb7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 21:54:13 -0700 Subject: [PATCH 021/165] Preserve File error state once error occurs. --- firmware/application/file.cpp | 43 +++++++++++++++++++++++++++-------- firmware/application/file.hpp | 3 ++- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index 7a815fc5..e2e99385 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -23,7 +23,11 @@ #include -File::File(const std::string& filename, openmode mode) { +File::File( + const std::string& filename, + openmode mode +) : err { FR_OK } +{ BYTE fatfs_mode = 0; if( mode & openmode::in ) { fatfs_mode |= FA_READ; @@ -38,9 +42,11 @@ File::File(const std::string& filename, openmode mode) { fatfs_mode |= FA_OPEN_ALWAYS; } - if( f_open(&f, filename.c_str(), fatfs_mode) == FR_OK ) { + err = f_open(&f, filename.c_str(), fatfs_mode); + if( err == FR_OK ) { if( mode & openmode::ate ) { - if( f_lseek(&f, f_size(&f)) != FR_OK ) { + err = f_lseek(&f, f_size(&f)); + if( err != FR_OK ) { f_close(&f); } } @@ -52,20 +58,33 @@ File::~File() { } bool File::read(void* const data, const size_t bytes_to_read) { + if( err != FR_OK ) { + return false; + } + UINT bytes_read = 0; - const auto result = f_read(&f, data, bytes_to_read, &bytes_read); - return (result == FR_OK) && (bytes_read == bytes_to_read); + err = f_read(&f, data, bytes_to_read, &bytes_read); + return (err == FR_OK); } bool File::write(const void* const data, const size_t bytes_to_write) { + if( err != FR_OK ) { + return false; + } + UINT bytes_written = 0; - const auto result = f_write(&f, data, bytes_to_write, &bytes_written); - return (result == FR_OK) && (bytes_written == bytes_to_write); + err = f_write(&f, data, bytes_to_write, &bytes_written); + return (err == FR_OK); } uint64_t File::seek(const uint64_t new_position) { + if( err != FR_OK ) { + return false; + } + const auto old_position = f_tell(&f); - if( f_lseek(&f, new_position) != FR_OK ) { + err = f_lseek(&f, new_position); + if( err != FR_OK ) { f_close(&f); } if( f_tell(&f) != new_position ) { @@ -80,8 +99,12 @@ bool File::puts(const std::string& string) { } bool File::sync() { - const auto result = f_sync(&f); - return (result == FR_OK); + if( err != FR_OK ) { + return false; + } + + err = f_sync(&f); + return (err == FR_OK); } static std::string find_last_file_matching_pattern(const std::string& pattern) { diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index 789d2310..34466c4c 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -126,7 +126,7 @@ public: ~File(); bool is_open() const { - return f_error(&f) == 0; + return err == FR_OK; } bool read(void* const data, const size_t bytes_to_read); @@ -145,6 +145,7 @@ public: private: FIL f; + uint32_t err; }; inline constexpr File::openmode operator|(File::openmode a, File::openmode b) { From 1df505331a9dcddb0f983f5511552ef93ca10cdd Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 21:55:01 -0700 Subject: [PATCH 022/165] Handle File errors beyond FatFs. --- firmware/application/file.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index e2e99385..8cf840a0 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -23,6 +23,12 @@ #include +/* Values added to FatFs FRESULT enum, values outside the FRESULT data type */ +static_assert(sizeof(FIL::err) == 1, "FatFs FIL::err size not expected."); +#define FR_DISK_FULL (0x100) +#define FR_EOF (0x101) +#define FR_BAD_SEEK (0x102) + File::File( const std::string& filename, openmode mode @@ -64,6 +70,9 @@ bool File::read(void* const data, const size_t bytes_to_read) { UINT bytes_read = 0; err = f_read(&f, data, bytes_to_read, &bytes_read); + if( bytes_read != bytes_to_read ) { + err = FR_EOF; + } return (err == FR_OK); } @@ -74,6 +83,9 @@ bool File::write(const void* const data, const size_t bytes_to_write) { UINT bytes_written = 0; err = f_write(&f, data, bytes_to_write, &bytes_written); + if( bytes_written != bytes_to_write ) { + err = FR_DISK_FULL; + } return (err == FR_OK); } @@ -88,6 +100,7 @@ uint64_t File::seek(const uint64_t new_position) { f_close(&f); } if( f_tell(&f) != new_position ) { + err = FR_BAD_SEEK; f_close(&f); } return old_position; @@ -95,6 +108,9 @@ uint64_t File::seek(const uint64_t new_position) { bool File::puts(const std::string& string) { const auto result = f_puts(string.c_str(), &f); + if( result != (int)string.size() ) { + err = FR_DISK_FULL; + } return (result >= 0); } @@ -185,6 +201,9 @@ std::string filesystem_error::what() const { case FR_NOT_ENOUGH_CORE: return "not enough core"; case FR_TOO_MANY_OPEN_FILES: return "too many open files"; case FR_INVALID_PARAMETER: return "invalid parameter"; + case FR_EOF: return "end of file"; + case FR_DISK_FULL: return "disk full"; + case FR_BAD_SEEK: return "bad seek"; default: return "unknown"; } } From 8655b6d91597c3a62e9a0e0cae53c5ff7578b9f1 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 21:55:39 -0700 Subject: [PATCH 023/165] Adapt filesystem_error to new File error handling, expose on File. --- firmware/application/file.hpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index 34466c4c..d8c711f2 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -37,11 +37,7 @@ namespace std { namespace filesystem { struct filesystem_error { - const BYTE err; - - operator bool() const { - return err != FR_OK; - } + const uint32_t err; std::string what() const; }; @@ -129,6 +125,14 @@ public: return err == FR_OK; } + bool bad() const { + return err != FR_OK; + } + + std::filesystem::filesystem_error error() const { + return { err }; + } + bool read(void* const data, const size_t bytes_to_read); bool write(const void* const data, const size_t bytes_to_write); From 87505f833b467d619099ea172f6f9b1510a84693 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 21:57:38 -0700 Subject: [PATCH 024/165] Expose filesystem errors on Writer. --- firmware/application/capture_thread.hpp | 4 ++++ firmware/application/ui_record_view.cpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index 5ebd4944..a8e5bb3e 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -26,6 +26,9 @@ #include "event_m0.hpp" +#include "file.hpp" +#include "optional.hpp" + #include #include #include @@ -33,6 +36,7 @@ class Writer { public: virtual bool write(const void* const buffer, const size_t bytes) = 0; + virtual Optional error() const = 0; virtual ~Writer() = default; }; diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 5e813a90..0eb67bc7 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -44,6 +44,14 @@ public: return file.write(buffer, bytes); } + Optional error() const override { + if( file.bad() ) { + return { file.error() }; + } else { + return { }; + } + } + private: File file; }; @@ -71,6 +79,14 @@ public: return success; } + Optional error() const override { + if( file.bad() ) { + return { file.error() }; + } else { + return { }; + } + } + private: struct fmt_pcm_t { constexpr fmt_pcm_t( From ebf0e765ce92e59dd87e4a74354797a712107a2b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 21:58:15 -0700 Subject: [PATCH 025/165] Expose Writer errors through CaptureThread. --- firmware/application/capture_thread.cpp | 9 +++++++++ firmware/application/capture_thread.hpp | 2 ++ 2 files changed, 11 insertions(+) diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index 64ad0753..0dbc4c1a 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -98,6 +98,15 @@ CaptureThread::~CaptureThread() { } } +Optional CaptureThread::error() const { + const auto error = writer->error(); + if( error.is_valid() ) { + return { error.value().what() }; + } else { + return { }; + } +} + void CaptureThread::check_fifo_isr() { // TODO: Prevent over-signalling by transmitting a set of // flags from the baseband core. diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index a8e5bb3e..25c09226 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -53,6 +53,8 @@ public: return config; } + Optional error() const; + static void check_fifo_isr(); private: From 92d75fa46d7a147b727cacf149567f48e0dd8fe5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 21:58:54 -0700 Subject: [PATCH 026/165] Very crude ModalMessageView. Initially for displaying filesystem errors. --- firmware/application/ui_navigation.cpp | 19 +++++++++++++++++++ firmware/application/ui_navigation.hpp | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 14f4cc6f..943d522a 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -273,4 +273,23 @@ void NotImplementedView::focus() { button_done.focus(); } +/* ModalMessageView ******************************************************/ + +ModalMessageView::ModalMessageView(NavigationView& nav, std::string message) { + button_done.on_select = [&nav](Button&){ + nav.pop(); + }; + + add_children({ { + &text_message, + &button_done, + } }); + + text_message.set(message); +} + +void ModalMessageView::focus() { + button_done.focus(); +} + } /* namespace ui */ diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index be5fb3c4..a932c907 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -205,6 +205,24 @@ private: }; }; +class ModalMessageView : public View { +public: + ModalMessageView(NavigationView& nav, std::string message); + + void focus() override; + +private: + Text text_message { + { 0 * 8, 7 * 16, 30 * 8, 16 }, + "" + }; + + Button button_done { + { 10 * 8, 13 * 16, 10 * 8, 24 }, + "OK", + }; +}; + } /* namespace ui */ #endif/*__UI_NAVIGATION_H__*/ From 9dc12fca3cee556e50c30542d0a51878abd0a194 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 21:59:46 -0700 Subject: [PATCH 027/165] Check for filesystem errors in RecordView. --- firmware/application/ui_record_view.cpp | 29 ++++++++++++++++++++----- firmware/application/ui_record_view.hpp | 4 ++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 0eb67bc7..8473838e 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -235,12 +235,19 @@ void RecordView::start() { }; if( writer ) { - text_record_filename.set(filename_stem); - button_record.set_bitmap(&bitmap_stop); - capture_thread = std::make_unique( - std::move(writer), - write_size, buffer_count - ); + const auto error = writer->error(); + if( error.is_valid() ) { + report_error(error.value().what()); + } else { + text_record_filename.set(filename_stem); + button_record.set_bitmap(&bitmap_stop); + capture_thread = std::make_unique( + std::move(writer), + write_size, buffer_count + ); + } + } else { + report_error("file type"); } } @@ -259,6 +266,10 @@ void RecordView::write_metadata_file(const std::string& filename) { void RecordView::on_tick_second() { if( is_active() ) { + const auto error = capture_thread->error(); + if( error.is_valid() ) { + report_error(error.value()); + } const auto dropped_percent = std::min(99U, capture_thread->state().dropped_percent()); const auto s = to_string_dec_uint(dropped_percent, 2, ' ') + "\%"; text_record_dropped.set(s); @@ -280,4 +291,10 @@ void RecordView::on_tick_second() { } } +void RecordView::report_error(const std::string& message) { + if( on_error ) { + on_error(message); + } +} + } /* namespace ui */ diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 5cbaabb4..8f987b3d 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -37,6 +37,8 @@ namespace ui { class RecordView : public View { public: + std::function on_error; + enum FileType { RawS16 = 2, WAV = 3, @@ -71,6 +73,8 @@ private: void on_tick_second(); + void report_error(const std::string& message); + const std::string filename_stem_pattern; const FileType file_type; const size_t write_size; From 8de12ff570d68e0c9c392ef6cb4a3ba92473ad10 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 22:00:40 -0700 Subject: [PATCH 028/165] Display modal error when RecordView experiences an error. --- firmware/application/analog_audio_app.cpp | 4 ++++ firmware/application/capture_app.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 948e6d5a..520b5684 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -139,6 +139,10 @@ AnalogAudioView::AnalogAudioView( this->on_headphone_volume_changed(v); }; + record_view.on_error = [&nav](std::string message) { + nav.push(message); + }; + audio::output::start(); update_modulation(static_cast(modulation)); diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index e03d9476..1226a575 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -70,6 +70,9 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { receiver_model.enable(); record_view.set_sampling_rate(sampling_rate / 8); + record_view.on_error = [&nav](std::string message) { + nav.push(message); + }; } CaptureAppView::~CaptureAppView() { From 537296b8c359cbf8a9e7eeaa4f951b1686f94110 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 22:03:25 -0700 Subject: [PATCH 029/165] Stop capture on error. --- firmware/application/ui_record_view.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 8473838e..7d984cce 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -268,6 +268,7 @@ void RecordView::on_tick_second() { if( is_active() ) { const auto error = capture_thread->error(); if( error.is_valid() ) { + stop(); report_error(error.value()); } const auto dropped_percent = std::min(99U, capture_thread->state().dropped_percent()); From ff5e20a7a4d3af9f0ad559a4f441f8f6612eb6a0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 12 May 2016 22:31:56 -0700 Subject: [PATCH 030/165] Refactor capture file writer classes -- lots of common code. --- firmware/application/ui_record_view.cpp | 55 ++++++++++--------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 7d984cce..cc87f0d5 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -32,18 +32,14 @@ using namespace portapack; #include -class RawFileWriter : public Writer { +class FileWriter : public Writer { public: - RawFileWriter( + FileWriter( const std::string& filename ) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc } { } - bool write(const void* const buffer, const size_t bytes) override { - return file.write(buffer, bytes); - } - Optional error() const override { if( file.bad() ) { return { file.error() }; @@ -52,25 +48,6 @@ public: } } -private: - File file; -}; - -class WAVFileWriter : public Writer { -public: - WAVFileWriter( - const std::string& filename, - size_t sampling_rate - ) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc }, - header { sampling_rate } - { - update_header(); - } - - ~WAVFileWriter() { - update_header(); - } - bool write(const void* const buffer, const size_t bytes) override { const auto success = file.write(buffer, bytes) ; if( success ) { @@ -79,12 +56,26 @@ public: return success; } - Optional error() const override { - if( file.bad() ) { - return { file.error() }; - } else { - return { }; - } +protected: + File file; + uint64_t bytes_written { 0 }; +}; + +using RawFileWriter = FileWriter; + +class WAVFileWriter : public FileWriter { +public: + WAVFileWriter( + const std::string& filename, + size_t sampling_rate + ) : RawFileWriter { filename }, + header { sampling_rate } + { + update_header(); + } + + ~WAVFileWriter() { + update_header(); } private: @@ -137,9 +128,7 @@ private: data_t data; }; - File file; header_t header; - uint64_t bytes_written { 0 }; void update_header() { header.set_data_size(bytes_written); From d905c446bf92adc946241732c4c2d10f9b5f483e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 13 May 2016 18:10:23 -0700 Subject: [PATCH 031/165] Fix integer width oops calculating disk space(). --- firmware/application/file.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index 8cf840a0..25eeda29 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -239,10 +239,11 @@ space_info space(const path& p) { #if _MAX_SS != _MIN_SS static_assert(false, "FatFs not configured for fixed sector size"); #else + const std::uintmax_t cluster_bytes = fs->csize * _MIN_SS; return { - (fs->n_fatent - 2) * fs->csize * _MIN_SS, - free_clusters * fs->csize * _MIN_SS, - free_clusters * fs->csize * _MIN_SS, + (fs->n_fatent - 2) * cluster_bytes, + free_clusters * cluster_bytes, + free_clusters * cluster_bytes, }; #endif } else { From 682a1706a3425bea9f441a702479ed9ba34b7eaf Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 16 May 2016 14:01:44 -0700 Subject: [PATCH 032/165] Improve File error handling. Massive effects... API is somewhat stolen from Rust std::fs::File. Static factories didn't work out so well, though. Move semantics made my head explode. TODO: Still a lot of places where errors aren't handled, but it's an improvement... --- firmware/application/ais_app.cpp | 27 ++--- firmware/application/ais_app.hpp | 6 +- firmware/application/capture_thread.cpp | 18 ++- firmware/application/capture_thread.hpp | 11 +- firmware/application/ert_app.cpp | 17 +-- firmware/application/ert_app.hpp | 6 +- firmware/application/file.cpp | 123 +++++++++---------- firmware/application/file.hpp | 118 +++++++++++++----- firmware/application/log_file.cpp | 20 ++-- firmware/application/log_file.hpp | 10 +- firmware/application/tpms_app.cpp | 21 ++-- firmware/application/tpms_app.hpp | 4 +- firmware/application/ui_navigation.cpp | 6 +- firmware/application/ui_record_view.cpp | 139 ++++++++++++++-------- firmware/application/ui_record_view.hpp | 2 +- firmware/application/ui_sd_card_debug.cpp | 20 ++-- firmware/common/png_writer.cpp | 12 +- firmware/common/png_writer.hpp | 3 +- 18 files changed, 328 insertions(+), 235 deletions(-) diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index 964ddf8d..f8e94878 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -126,25 +126,17 @@ static std::string true_heading(const TrueHeading value) { } /* namespace format */ } /* namespace ais */ -AISLogger::AISLogger( - const std::string& file_path -) : log_file { file_path } -{ -} - void AISLogger::on_packet(const ais::Packet& packet) { // TODO: Unstuff here, not in baseband! - if( log_file.is_open() ) { - std::string entry; - entry.reserve((packet.length() + 3) / 4); + std::string entry; + entry.reserve((packet.length() + 3) / 4); - for(size_t i=0; i= 10) ? ('W' + nibble) : ('0' + nibble); - } - - log_file.write_entry(packet.received_at(), entry); + for(size_t i=0; i= 10) ? ('W' + nibble) : ('0' + nibble); } + + log_file.write_entry(packet.received_at(), entry); } void AISRecentEntry::update(const ais::Packet& packet) { @@ -332,7 +324,10 @@ AISAppView::AISAppView(NavigationView&) { this->on_show_list(); }; - logger = std::make_unique("ais.txt"); + logger = std::make_unique(); + if( logger ) { + logger->append("ais.txt"); + } } AISAppView::~AISAppView() { diff --git a/firmware/application/ais_app.hpp b/firmware/application/ais_app.hpp index a166f47d..19286e6d 100644 --- a/firmware/application/ais_app.hpp +++ b/firmware/application/ais_app.hpp @@ -92,8 +92,10 @@ using AISRecentEntries = RecentEntries; class AISLogger { public: - AISLogger(const std::string& file_path); - + Optional append(const std::string& filename) { + return log_file.append(filename); + } + void on_packet(const ais::Packet& packet); private: diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index 0dbc4c1a..50ed7a27 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -98,13 +98,8 @@ CaptureThread::~CaptureThread() { } } -Optional CaptureThread::error() const { - const auto error = writer->error(); - if( error.is_valid() ) { - return { error.value().what() }; - } else { - return { }; - } +const Optional& CaptureThread::error() const { + return last_error; } void CaptureThread::check_fifo_isr() { @@ -118,14 +113,15 @@ void CaptureThread::check_fifo_isr() { } } -msg_t CaptureThread::run() { +Optional CaptureThread::run() { StreamOutput stream { &config }; while( !chThdShouldTerminate() ) { if( stream.available() ) { auto buffer = stream.get_buffer(); - if( !writer->write(buffer->data(), buffer->size()) ) { - return false; + auto write_result = writer->write(buffer->data(), buffer->size()); + if( write_result.is_error() ) { + return write_result.error(); } stream.release_buffer(buffer); } else { @@ -133,5 +129,5 @@ msg_t CaptureThread::run() { } } - return true; + return { }; } diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index 25c09226..6842982c 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -35,8 +35,7 @@ class Writer { public: - virtual bool write(const void* const buffer, const size_t bytes) = 0; - virtual Optional error() const = 0; + virtual File::Result write(const void* const buffer, const size_t bytes) = 0; virtual ~Writer() = default; }; @@ -53,21 +52,23 @@ public: return config; } - Optional error() const; + const Optional& error() const; static void check_fifo_isr(); private: CaptureConfig config; std::unique_ptr writer; + Optional last_error; static Thread* thread; static msg_t static_fn(void* arg) { auto obj = static_cast(arg); - return obj->run(); + obj->last_error = obj->run(); + return 0; } - msg_t run(); + Optional run(); }; #endif/*__CAPTURE_THREAD_H__*/ diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 86b93339..61501b47 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -57,17 +57,9 @@ std::string commodity_type(CommodityType value) { } /* namespace ert */ -ERTLogger::ERTLogger( - const std::string& file_path -) : log_file { file_path } -{ -} - void ERTLogger::on_packet(const ert::Packet& packet) { - if( log_file.is_open() ) { - const auto formatted = packet.symbols_formatted(); - log_file.write_entry(packet.received_at(), formatted.data + "/" + formatted.errors); - } + const auto formatted = packet.symbols_formatted(); + log_file.write_entry(packet.received_at(), formatted.data + "/" + formatted.errors); } const ERTRecentEntry::Key ERTRecentEntry::invalid_key { }; @@ -148,7 +140,10 @@ ERTAppView::ERTAppView(NavigationView&) { .decimation_factor = 1, }); - logger = std::make_unique("ert.txt"); + logger = std::make_unique(); + if( logger ) { + logger->append("ert.txt"); + } } ERTAppView::~ERTAppView() { diff --git a/firmware/application/ert_app.hpp b/firmware/application/ert_app.hpp index 403d9b63..b74d599e 100644 --- a/firmware/application/ert_app.hpp +++ b/firmware/application/ert_app.hpp @@ -87,8 +87,10 @@ struct ERTRecentEntry { class ERTLogger { public: - ERTLogger(const std::string& file_path); - + Optional append(const std::string& filename) { + return log_file.append(filename); + } + void on_packet(const ert::Packet& packet); private: diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index 25eeda29..bcca3742 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -28,99 +28,93 @@ static_assert(sizeof(FIL::err) == 1, "FatFs FIL::err size not expected."); #define FR_DISK_FULL (0x100) #define FR_EOF (0x101) #define FR_BAD_SEEK (0x102) +#define FR_UNEXPECTED (0x103) -File::File( - const std::string& filename, - openmode mode -) : err { FR_OK } -{ - BYTE fatfs_mode = 0; - if( mode & openmode::in ) { - fatfs_mode |= FA_READ; - } - if( mode & openmode::out ) { - fatfs_mode |= FA_WRITE; - } - if( mode & openmode::trunc ) { - fatfs_mode |= FA_CREATE_ALWAYS; - } - if( mode & openmode::ate ) { - fatfs_mode |= FA_OPEN_ALWAYS; - } - - err = f_open(&f, filename.c_str(), fatfs_mode); - if( err == FR_OK ) { - if( mode & openmode::ate ) { - err = f_lseek(&f, f_size(&f)); - if( err != FR_OK ) { +Optional File::open_fatfs(const std::string& filename, BYTE mode) { + auto result = f_open(&f, filename.c_str(), mode); + if( result == FR_OK ) { + if( mode & FA_OPEN_ALWAYS ) { + const auto result = f_lseek(&f, f_size(&f)); + if( result != FR_OK ) { f_close(&f); } } } + + if( result == FR_OK ) { + return { }; + } else { + return { result }; + } +} + +Optional File::open(const std::string& filename) { + return open_fatfs(filename, FA_READ); +} + +Optional File::append(const std::string& filename) { + return open_fatfs(filename, FA_WRITE | FA_OPEN_ALWAYS); +} + +Optional File::create(const std::string& filename) { + return open_fatfs(filename, FA_WRITE | FA_CREATE_ALWAYS); } File::~File() { f_close(&f); } -bool File::read(void* const data, const size_t bytes_to_read) { - if( err != FR_OK ) { - return false; - } - +File::Result File::read(void* const data, const size_t bytes_to_read) { UINT bytes_read = 0; - err = f_read(&f, data, bytes_to_read, &bytes_read); - if( bytes_read != bytes_to_read ) { - err = FR_EOF; + const auto result = f_read(&f, data, bytes_to_read, &bytes_read); + if( result == FR_OK ) { + return { static_cast(bytes_read) }; + } else { + return { static_cast(result) }; } - return (err == FR_OK); } -bool File::write(const void* const data, const size_t bytes_to_write) { - if( err != FR_OK ) { - return false; - } - +File::Result File::write(const void* const data, const size_t bytes_to_write) { UINT bytes_written = 0; - err = f_write(&f, data, bytes_to_write, &bytes_written); - if( bytes_written != bytes_to_write ) { - err = FR_DISK_FULL; + const auto result = f_write(&f, data, bytes_to_write, &bytes_written); + if( result == FR_OK ) { + return { static_cast(bytes_written) }; + } else { + return { static_cast(result) }; } - return (err == FR_OK); } -uint64_t File::seek(const uint64_t new_position) { - if( err != FR_OK ) { - return false; - } - +File::Result File::seek(const uint64_t new_position) { + /* NOTE: Returns *old* position, not new position */ const auto old_position = f_tell(&f); - err = f_lseek(&f, new_position); - if( err != FR_OK ) { - f_close(&f); + const auto result = f_lseek(&f, new_position); + if( result != FR_OK ) { + return { static_cast(result) }; } if( f_tell(&f) != new_position ) { - err = FR_BAD_SEEK; - f_close(&f); + return { static_cast(FR_BAD_SEEK) }; } - return old_position; + return { static_cast(old_position) }; } -bool File::puts(const std::string& string) { +File::Result File::puts(const std::string& string) { const auto result = f_puts(string.c_str(), &f); - if( result != (int)string.size() ) { - err = FR_DISK_FULL; + if( result >= 0 ) { + return { static_cast(result) }; + } else if( result == EOF ) { + return { static_cast(f_error(&f)) }; + } else { + return { static_cast(FR_UNEXPECTED) }; } - return (result >= 0); } -bool File::sync() { - if( err != FR_OK ) { - return false; +Optional File::sync() { + const auto result = f_sync(&f); + if( result == FR_OK ) { + return { }; + } else { + return { result }; } - - err = f_sync(&f); - return (err == FR_OK); } static std::string find_last_file_matching_pattern(const std::string& pattern) { @@ -181,7 +175,7 @@ namespace filesystem { std::string filesystem_error::what() const { switch(err) { - case FR_OK: return ""; + case FR_OK: return "ok"; case FR_DISK_ERR: return "disk error"; case FR_INT_ERR: return "insanity detected"; case FR_NOT_READY: return "not ready"; @@ -204,6 +198,7 @@ std::string filesystem_error::what() const { case FR_EOF: return "end of file"; case FR_DISK_FULL: return "disk full"; case FR_BAD_SEEK: return "bad seek"; + case FR_UNEXPECTED: return "unexpected"; default: return "unknown"; } } diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index d8c711f2..6d3453e6 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -24,6 +24,8 @@ #include "ff.h" +#include "optional.hpp" + #include #include #include @@ -37,9 +39,27 @@ namespace std { namespace filesystem { struct filesystem_error { - const uint32_t err; + constexpr filesystem_error( + ) : err { FR_OK } + { + } + + constexpr filesystem_error( + FRESULT fatfs_error + ) : err { fatfs_error } + { + } + + constexpr filesystem_error( + unsigned int other_error + ) : err { other_error } + { + } std::string what() const; + +private: + uint32_t err; }; using path = std::string; @@ -109,51 +129,89 @@ space_info space(const path& p); class File { public: - enum openmode { - app = 0x100, - binary = 0x200, - in = FA_READ, - out = FA_WRITE, - trunc = FA_CREATE_ALWAYS, - ate = FA_OPEN_ALWAYS, + using Error = std::filesystem::filesystem_error; + + template + struct Result { + enum class Type { + Success, + Error, + } type; + union { + T value_; + Error error_; + }; + + bool is_ok() const { + return type == Type::Success; + } + + bool is_error() const { + return type == Type::Error; + } + + const T& value() { + return value_; + } + + Error error() const { + return error_; + } + + Result() = delete; + + constexpr Result( + T value + ) : type { Type::Success }, + value_ { value } + { + } + + constexpr Result( + Error error + ) : type { Type::Error }, + error_ { error } + { + } + + ~Result() { + if( type == Type::Success ) { + value_.~T(); + } + } }; - File(const std::string& filename, openmode mode); + File() { }; ~File(); - bool is_open() const { - return err == FR_OK; - } + /* Prevent copies */ + File(const File&) = delete; + File& operator=(const File&) = delete; - bool bad() const { - return err != FR_OK; - } + // TODO: Return Result<>. + Optional open(const std::string& filename); + Optional append(const std::string& filename); + Optional create(const std::string& filename); - std::filesystem::filesystem_error error() const { - return { err }; - } + Result read(void* const data, const size_t bytes_to_read); + Result write(const void* const data, const size_t bytes_to_write); - bool read(void* const data, const size_t bytes_to_read); - bool write(const void* const data, const size_t bytes_to_write); - - uint64_t seek(const uint64_t new_position); + Result seek(const uint64_t new_position); template - bool write(const std::array& data) { + Result write(const std::array& data) { return write(data.data(), N); } - bool puts(const std::string& string); + Result puts(const std::string& string); - bool sync(); + // TODO: Return Result<>. + Optional sync(); private: FIL f; - uint32_t err; + + Optional open_fatfs(const std::string& filename, BYTE mode); }; -inline constexpr File::openmode operator|(File::openmode a, File::openmode b) { - return File::openmode(static_cast(a) | static_cast(b)); -} - #endif/*__FILE_H__*/ diff --git a/firmware/application/log_file.cpp b/firmware/application/log_file.cpp index 06e56246..a761650f 100644 --- a/firmware/application/log_file.cpp +++ b/firmware/application/log_file.cpp @@ -23,21 +23,15 @@ #include "string_format.hpp" -LogFile::LogFile( - const std::string& file_path -) : file { file_path, File::openmode::out | File::openmode::ate } -{ -} - -bool LogFile::is_open() const { - return file.is_open(); -} - -bool LogFile::write_entry(const rtc::RTC& datetime, const std::string& entry) { +File::Result LogFile::write_entry(const rtc::RTC& datetime, const std::string& entry) { std::string timestamp = to_string_timestamp(datetime); return write(timestamp + " " + entry + "\r\n"); } -bool LogFile::write(const std::string& message) { - return file.puts(message) && file.sync(); +File::Result LogFile::write(const std::string& message) { + auto puts_result = file.puts(message); + if( puts_result.is_ok() ) { + file.sync(); + } + return puts_result; } diff --git a/firmware/application/log_file.hpp b/firmware/application/log_file.hpp index 70a1651c..2aa515fa 100644 --- a/firmware/application/log_file.hpp +++ b/firmware/application/log_file.hpp @@ -31,16 +31,16 @@ using namespace lpc43xx; class LogFile { public: - LogFile(const std::string& file_path); + Optional append(const std::string& filename) { + return file.append(filename); + } - bool is_open() const; - - bool write_entry(const rtc::RTC& datetime, const std::string& entry); + File::Result write_entry(const rtc::RTC& datetime, const std::string& entry); private: File file; - bool write(const std::string& message); + File::Result write(const std::string& message); }; #endif/*__LOG_FILE_H__*/ diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index 46f04537..d6e1ef9f 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -51,22 +51,14 @@ std::string temperature(Temperature temperature) { } /* namespace tpms */ -TPMSLogger::TPMSLogger( - const std::string& file_path -) : log_file { file_path } -{ -} - void TPMSLogger::on_packet(const tpms::Packet& packet, const uint32_t target_frequency) { const auto hex_formatted = packet.symbols_formatted(); - if( log_file.is_open() ) { - // TODO: function doesn't take uint64_t, so when >= 1<<32, weirdness will ensue! - const auto tuning_frequency_str = to_string_dec_uint(target_frequency, 10); + // TODO: function doesn't take uint64_t, so when >= 1<<32, weirdness will ensue! + const auto tuning_frequency_str = to_string_dec_uint(target_frequency, 10); - std::string entry = tuning_frequency_str + " FSK 38.4 19.2 " + hex_formatted.data + "/" + hex_formatted.errors; - log_file.write_entry(packet.received_at(), entry); - } + std::string entry = tuning_frequency_str + " FSK 38.4 19.2 " + hex_formatted.data + "/" + hex_formatted.errors; + log_file.write_entry(packet.received_at(), entry); } const TPMSRecentEntry::Key TPMSRecentEntry::invalid_key = { tpms::Reading::Type::None, 0 }; @@ -165,7 +157,10 @@ TPMSAppView::TPMSAppView(NavigationView&) { .decimation_factor = 1, }); - logger = std::make_unique("tpms.txt"); + logger = std::make_unique(); + if( logger ) { + logger->append("tpms.txt"); + } } TPMSAppView::~TPMSAppView() { diff --git a/firmware/application/tpms_app.hpp b/firmware/application/tpms_app.hpp index ea0e9b39..e4f00b7a 100644 --- a/firmware/application/tpms_app.hpp +++ b/firmware/application/tpms_app.hpp @@ -72,7 +72,9 @@ using TPMSRecentEntries = RecentEntries; class TPMSLogger { public: - TPMSLogger(const std::string& file_path); + Optional append(const std::string& filename) { + return log_file.append(filename); + } void on_packet(const tpms::Packet& packet, const uint32_t target_frequency); diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 943d522a..bc1a7734 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -86,7 +86,11 @@ void SystemStatusView::on_camera() { return; } - PNGWriter png { filename_stem + ".PNG" }; + PNGWriter png; + auto create_error = png.create(filename_stem + ".PNG"); + if( create_error.is_valid() ) { + return; + } for(int i=0; i<320; i++) { std::array row; diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index cc87f0d5..6922a3e4 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -34,26 +34,23 @@ using namespace portapack; class FileWriter : public Writer { public: - FileWriter( - const std::string& filename - ) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc } - { + FileWriter() = default; + + FileWriter(const FileWriter&) = delete; + FileWriter& operator=(const FileWriter&) = delete; + FileWriter(FileWriter&& file) = delete; + FileWriter& operator=(FileWriter&&) = delete; + + Optional create(const std::string& filename) { + return file.create(filename); } - Optional error() const override { - if( file.bad() ) { - return { file.error() }; - } else { - return { }; + File::Result write(const void* const buffer, const size_t bytes) override { + auto write_result = file.write(buffer, bytes) ; + if( write_result.is_ok() ) { + bytes_written += write_result.value(); } - } - - bool write(const void* const buffer, const size_t bytes) override { - const auto success = file.write(buffer, bytes) ; - if( success ) { - bytes_written += bytes; - } - return success; + return write_result; } protected: @@ -66,18 +63,33 @@ using RawFileWriter = FileWriter; class WAVFileWriter : public FileWriter { public: WAVFileWriter( - const std::string& filename, size_t sampling_rate - ) : RawFileWriter { filename }, - header { sampling_rate } + ) : header { sampling_rate } { - update_header(); } + + WAVFileWriter(const WAVFileWriter&) = delete; + WAVFileWriter& operator=(const WAVFileWriter&) = delete; + WAVFileWriter(WAVFileWriter&&) = delete; + WAVFileWriter& operator=(WAVFileWriter&&) = delete; + ~WAVFileWriter() { update_header(); } + Optional create( + const std::string& filename + ) { + const auto create_error = FileWriter::create(filename); + if( create_error.is_valid() ) { + return create_error; + } else { + update_header(); + return { }; + } + } + private: struct fmt_pcm_t { constexpr fmt_pcm_t( @@ -132,7 +144,11 @@ private: void update_header() { header.set_data_size(bytes_written); - const auto old_position = file.seek(0); + auto seek_result = file.seek(0); + if( seek_result.is_error() ) { + return; + } + const auto old_position = seek_result.value(); file.write(&header, sizeof(header)); file.seek(old_position); } @@ -206,17 +222,39 @@ void RecordView::start() { std::unique_ptr writer; switch(file_type) { case FileType::WAV: - writer = std::make_unique( - filename_stem + ".WAV", - sampling_rate - ); + { + auto p = std::make_unique( + sampling_rate + ); + auto create_error = p->create( + filename_stem + ".WAV" + ); + if( create_error.is_valid() ) { + report_error(create_error.value().what()); + } else { + writer = std::move(p); + } + } break; case FileType::RawS16: - write_metadata_file(filename_stem + ".TXT"); - writer = std::make_unique( - filename_stem + ".C16" - ); + { + const auto metadata_file_error = write_metadata_file(filename_stem + ".TXT"); + if( metadata_file_error.is_valid() ) { + report_error(metadata_file_error.value().what()); + return; + } + + auto p = std::make_unique(); + auto create_error = p->create( + filename_stem + ".C16" + ); + if( create_error.is_valid() ) { + report_error(create_error.value().what()); + } else { + writer = std::move(p); + } + } break; default: @@ -224,19 +262,12 @@ void RecordView::start() { }; if( writer ) { - const auto error = writer->error(); - if( error.is_valid() ) { - report_error(error.value().what()); - } else { - text_record_filename.set(filename_stem); - button_record.set_bitmap(&bitmap_stop); - capture_thread = std::make_unique( - std::move(writer), - write_size, buffer_count - ); - } - } else { - report_error("file type"); + text_record_filename.set(filename_stem); + button_record.set_bitmap(&bitmap_stop); + capture_thread = std::make_unique( + std::move(writer), + write_size, buffer_count + ); } } @@ -247,10 +278,22 @@ void RecordView::stop() { } } -void RecordView::write_metadata_file(const std::string& filename) { - File file { filename, File::openmode::out | File::openmode::trunc }; - file.puts("sample_rate=" + to_string_dec_uint(sampling_rate) + "\n"); - file.puts("center_frequency=" + to_string_dec_uint(receiver_model.tuning_frequency()) + "\n"); +Optional RecordView::write_metadata_file(const std::string& filename) { + File file; + const auto create_error = file.create(filename); + if( create_error.is_valid() ) { + return create_error; + } else { + const auto puts_result1 = file.puts("sample_rate=" + to_string_dec_uint(sampling_rate) + "\n"); + if( puts_result1.is_error() ) { + return { puts_result1.error() }; + } + const auto puts_result2 = file.puts("center_frequency=" + to_string_dec_uint(receiver_model.tuning_frequency()) + "\n"); + if( puts_result2.is_error() ) { + return { puts_result2.error() }; + } + return { }; + } } void RecordView::on_tick_second() { @@ -258,7 +301,7 @@ void RecordView::on_tick_second() { const auto error = capture_thread->error(); if( error.is_valid() ) { stop(); - report_error(error.value()); + report_error(error.value().what()); } const auto dropped_percent = std::min(99U, capture_thread->state().dropped_percent()); const auto s = to_string_dec_uint(dropped_percent, 2, ' ') + "\%"; diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 8f987b3d..af21987d 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -69,7 +69,7 @@ public: private: void toggle(); - void write_metadata_file(const std::string& filename); + Optional write_metadata_file(const std::string& filename); void on_tick_second(); diff --git a/firmware/application/ui_sd_card_debug.cpp b/firmware/application/ui_sd_card_debug.cpp index 668c814b..eac201ea 100644 --- a/firmware/application/ui_sd_card_debug.cpp +++ b/firmware/application/ui_sd_card_debug.cpp @@ -134,22 +134,24 @@ private: return Result::FailHeap; } - File file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc }; - if( !file.is_open() ) { + File file; + auto file_create_error = file.create(filename); + if( file_create_error.is_valid() ) { return Result::FailFileOpenWrite; } lfsr_word_t v = 1; const halrtcnt_t test_start = halGetCounterValue(); - while( !chThdShouldTerminate() && file.is_open() && (_stats.write_bytes < bytes_to_write) ) { + while( !chThdShouldTerminate() && (_stats.write_bytes < bytes_to_write) ) { lfsr_fill(v, reinterpret_cast(buffer->data()), sizeof(*buffer.get()) / sizeof(lfsr_word_t) ); const halrtcnt_t write_start = halGetCounterValue(); - if( !file.write(buffer->data(), buffer->size()) ) { + const auto result_write = file.write(buffer->data(), buffer->size()); + if( result_write.is_error() ) { break; } const halrtcnt_t write_end = halGetCounterValue(); @@ -179,17 +181,19 @@ private: return Result::FailHeap; } - File file { filename, File::openmode::in | File::openmode::binary }; - if( !file.is_open() ) { + File file; + auto file_open_error = file.open(filename); + if( file_open_error.is_valid() ) { return Result::FailFileOpenRead; } lfsr_word_t v = 1; const halrtcnt_t test_start = halGetCounterValue(); - while( !chThdShouldTerminate() && file.is_open() && (_stats.read_bytes < bytes_to_read) ) { + while( !chThdShouldTerminate() && (_stats.read_bytes < bytes_to_read) ) { const halrtcnt_t read_start = halGetCounterValue(); - if( !file.read(buffer->data(), buffer->size()) ) { + const auto result_read = file.read(buffer->data(), buffer->size()); + if( result_read.is_error() ) { break; } const halrtcnt_t read_end = halGetCounterValue(); diff --git a/firmware/common/png_writer.cpp b/firmware/common/png_writer.cpp index c1d59244..e1667f14 100644 --- a/firmware/common/png_writer.cpp +++ b/firmware/common/png_writer.cpp @@ -49,10 +49,14 @@ static constexpr std::array png_iend { { 0xae, 0x42, 0x60, 0x82, // CRC } }; -PNGWriter::PNGWriter( +Optional PNGWriter::create( const std::string& filename -) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc } -{ +) { + const auto create_error = file.create(filename); + if( create_error.is_valid() ) { + return create_error; + } + file.write(png_file_header); file.write(png_ihdr_screen_capture); @@ -63,6 +67,8 @@ PNGWriter::PNGWriter( constexpr std::array zlib_header { 0x78, 0x01 }; // Zlib CM, CINFO, FLG. write_chunk_content(zlib_header); + + return { }; } PNGWriter::~PNGWriter() { diff --git a/firmware/common/png_writer.hpp b/firmware/common/png_writer.hpp index 90fc2086..37bede47 100644 --- a/firmware/common/png_writer.hpp +++ b/firmware/common/png_writer.hpp @@ -33,9 +33,10 @@ class PNGWriter { public: - explicit PNGWriter(const std::string& filename); ~PNGWriter(); + Optional create(const std::string& filename); + void write_scanline(const std::array& scanline); private: From 6a3cd4c144b2fef5c74730020c5e8d7295042b5f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 May 2016 09:33:16 -0700 Subject: [PATCH 033/165] Centralize handling of modal error display. --- firmware/application/analog_audio_app.cpp | 2 +- firmware/application/capture_app.cpp | 2 +- firmware/application/ui_navigation.cpp | 11 +++++++++++ firmware/application/ui_navigation.hpp | 3 +++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 520b5684..408b13be 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -140,7 +140,7 @@ AnalogAudioView::AnalogAudioView( }; record_view.on_error = [&nav](std::string message) { - nav.push(message); + nav.display_error(message); }; audio::output::start(); diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 1226a575..160066b0 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -71,7 +71,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { record_view.set_sampling_rate(sampling_rate / 8); record_view.on_error = [&nav](std::string message) { - nav.push(message); + nav.display_error(message); }; } diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index bc1a7734..6fb735af 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -117,6 +117,10 @@ View* NavigationView::push_view(std::unique_ptr new_view) { } void NavigationView::pop() { + if( view() == modal_view ) { + modal_view = nullptr; + } + // Can't pop last item from stack. if( view_stack.size() > 1 ) { free_view(); @@ -127,6 +131,13 @@ void NavigationView::pop() { } } +void NavigationView::display_error(const std::string& message) { + /* If a modal view is already visible, don't display another */ + if( !modal_view ) { + modal_view = push(message); + } +} + void NavigationView::free_view() { remove_child(view()); } diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index a932c907..b103189b 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -102,10 +102,13 @@ public: void pop(); + void display_error(const std::string& message); + void focus() override; private: std::vector> view_stack; + Widget* modal_view { nullptr }; Widget* view() const; From ac49726707a713d8f11ab0384dc8974817112fa8 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 May 2016 10:15:34 -0700 Subject: [PATCH 034/165] Rename display_error() -> display_modal(), add title argument. --- firmware/application/analog_audio_app.cpp | 2 +- firmware/application/capture_app.cpp | 2 +- firmware/application/ui_navigation.cpp | 14 +++++++++++--- firmware/application/ui_navigation.hpp | 12 ++++++++++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 408b13be..44d72c42 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -140,7 +140,7 @@ AnalogAudioView::AnalogAudioView( }; record_view.on_error = [&nav](std::string message) { - nav.display_error(message); + nav.display_modal("Error", message); }; audio::output::start(); diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 160066b0..cff3bf0b 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -71,7 +71,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { record_view.set_sampling_rate(sampling_rate / 8); record_view.on_error = [&nav](std::string message) { - nav.display_error(message); + nav.display_modal("Error", message); }; } diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 6fb735af..3841cb97 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -131,10 +131,13 @@ void NavigationView::pop() { } } -void NavigationView::display_error(const std::string& message) { +void NavigationView::display_modal( + const std::string& title, + const std::string& message +) { /* If a modal view is already visible, don't display another */ if( !modal_view ) { - modal_view = push(message); + modal_view = push(title, message); } } @@ -290,7 +293,12 @@ void NotImplementedView::focus() { /* ModalMessageView ******************************************************/ -ModalMessageView::ModalMessageView(NavigationView& nav, std::string message) { +ModalMessageView::ModalMessageView( + NavigationView& nav, + const std::string& title, + const std::string& message +) : title_ { title } +{ button_done.on_select = [&nav](Button&){ nav.pop(); }; diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index b103189b..b53a237c 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -102,7 +102,7 @@ public: void pop(); - void display_error(const std::string& message); + void display_modal(const std::string& title, const std::string& message); void focus() override; @@ -210,11 +210,19 @@ private: class ModalMessageView : public View { public: - ModalMessageView(NavigationView& nav, std::string message); + ModalMessageView( + NavigationView& nav, + const std::string& title, + const std::string& message + ); void focus() override; + std::string title() const override { return title_; }; + private: + const std::string title_; + Text text_message { { 0 * 8, 7 * 16, 30 * 8, 16 }, "" From 65d2f263f21154db3e88a72f36dd48faba1d71ec Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 May 2016 10:29:49 -0700 Subject: [PATCH 035/165] Center modal view message. --- firmware/application/ui_navigation.cpp | 6 ++++++ firmware/application/ui_navigation.hpp | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 3841cb97..bb554d05 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -309,6 +309,12 @@ ModalMessageView::ModalMessageView( } }); text_message.set(message); + + const int text_message_width = message.size() * 8; + text_message.set_parent_rect({ + (240 - text_message_width) / 2, 7 * 16, + text_message_width, 16 + }); } void ModalMessageView::focus() { diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index b53a237c..65fcf2fe 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -223,10 +223,7 @@ public: private: const std::string title_; - Text text_message { - { 0 * 8, 7 * 16, 30 * 8, 16 }, - "" - }; + Text text_message { }; Button button_done { { 10 * 8, 13 * 16, 10 * 8, 24 }, From ad554b28b5d4fac4f9d64ff7f819aa77a516615f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 May 2016 11:11:30 -0700 Subject: [PATCH 036/165] Rename TPMS clock recovery, packet builders for accuracy. --- firmware/baseband/proc_tpms.cpp | 6 +++--- firmware/baseband/proc_tpms.hpp | 9 +++++---- firmware/common/tpms_packet.cpp | 4 ++-- firmware/common/tpms_packet.hpp | 4 ++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index 9d401a1c..497f466f 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -48,10 +48,10 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { const auto sliced = ook_slicer_5sps(decim_1_out.p[i]); slicer_history = (slicer_history << 1) | sliced; - ook_clock_recovery_subaru(slicer_history, [this](const bool symbol) { - this->packet_builder_ook_subaru.execute(symbol); + clock_recovery_ook_8k192(slicer_history, [this](const bool symbol) { + this->packet_builder_schrader.execute(symbol); }); - ook_clock_recovery_gmc(slicer_history, [this](const bool symbol) { + clock_recovery_ook_8k4(slicer_history, [this](const bool symbol) { this->packet_builder_ook_gmc.execute(symbol); }); } diff --git a/firmware/baseband/proc_tpms.hpp b/firmware/baseband/proc_tpms.hpp index 759f7383..d9f6f3d5 100644 --- a/firmware/baseband/proc_tpms.hpp +++ b/firmware/baseband/proc_tpms.hpp @@ -92,20 +92,21 @@ private: OOKSlicerMagSquaredInt ook_slicer_5sps { 5 }; uint32_t slicer_history { 0 }; - OOKClockRecovery ook_clock_recovery_subaru { + OOKClockRecovery clock_recovery_ook_8k192 { channel_sample_rate / 8192.0f }; - PacketBuilder packet_builder_ook_subaru { + PacketBuilder packet_builder_schrader { { 0b010101010101010101011110, 24, 0 }, { }, { 80 }, [](const baseband::Packet& packet) { - const TPMSPacketMessage message { tpms::SignalType::Subaru, packet }; + const TPMSPacketMessage message { tpms::SignalType::Schrader, packet }; shared_memory.application_queue.push(message); } }; - OOKClockRecovery ook_clock_recovery_gmc { + + OOKClockRecovery clock_recovery_ook_8k4 { channel_sample_rate / 8400.0f }; diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index 7b18622b..0d800232 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -67,9 +67,9 @@ Optional Packet::reading(const SignalType signal_type) const { } } - if( signal_type == SignalType::Subaru ) { + if( signal_type == SignalType::Schrader ) { return Reading { - Reading::Type::SUB_35, + Reading::Type::Schrader, reader_.read(3, 25), Pressure { static_cast(reader_.read(28, 8)) } }; diff --git a/firmware/common/tpms_packet.hpp b/firmware/common/tpms_packet.hpp index ab9ecf4f..57d8d929 100644 --- a/firmware/common/tpms_packet.hpp +++ b/firmware/common/tpms_packet.hpp @@ -39,7 +39,7 @@ namespace tpms { enum SignalType : uint32_t { FLM = 1, - Subaru = 2, + Schrader = 2, GMC = 3, }; @@ -71,7 +71,7 @@ public: FLM_64 = 1, FLM_72 = 2, FLM_80 = 3, - SUB_35 = 4, + Schrader = 4, GMC_96 = 5, }; From 9e3ac94187eaf1ee1aa069030dfe08d731690523 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 May 2016 11:24:33 -0700 Subject: [PATCH 037/165] A bit more TPMS member variable renaming. --- firmware/baseband/proc_tpms.cpp | 2 +- firmware/baseband/proc_tpms.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index 497f466f..cf061d10 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -40,7 +40,7 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { for(size_t i=0; i clock_recovery { + clock_recovery::ClockRecovery clock_recovery_fsk_19k2 { 38400, 19200, { 0.0555f }, [this](const float symbol) { this->consume_symbol(symbol); } }; From d81d879aac542a5929498bd3da7221bf844ce5ca Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 May 2016 11:26:17 -0700 Subject: [PATCH 038/165] Shrink understood TPMS packet payload sizes to minimum required. --- firmware/baseband/proc_tpms.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/baseband/proc_tpms.hpp b/firmware/baseband/proc_tpms.hpp index 506d83e6..fda7126e 100644 --- a/firmware/baseband/proc_tpms.hpp +++ b/firmware/baseband/proc_tpms.hpp @@ -80,7 +80,7 @@ private: PacketBuilder packet_builder { { 0b010101010101010101010101010110, 30, 1 }, { }, - { 256 }, + { 160 }, [this](const baseband::Packet& packet) { this->payload_handler(packet); } @@ -99,7 +99,7 @@ private: PacketBuilder packet_builder_schrader { { 0b010101010101010101011110, 24, 0 }, { }, - { 80 }, + { 74 }, [](const baseband::Packet& packet) { const TPMSPacketMessage message { tpms::SignalType::Schrader, packet }; shared_memory.application_queue.push(message); From 40859444fee53479242c5fcc7e15c6e5c9c0dc0e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 May 2016 11:27:19 -0700 Subject: [PATCH 039/165] Update TPMS field handling for Schrader devices. Thanks to mossmann for discovering these details. --- firmware/common/tpms_packet.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index 0d800232..0fc57dd3 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -68,10 +68,13 @@ Optional Packet::reading(const SignalType signal_type) const { } if( signal_type == SignalType::Schrader ) { + const auto flags = reader_.read(0, 3); + const auto checksum = reader_.read(35, 2); + return Reading { Reading::Type::Schrader, - reader_.read(3, 25), - Pressure { static_cast(reader_.read(28, 8)) } + reader_.read(3, 24), + Pressure { static_cast(reader_.read(27, 8)) } }; } From 05df04df7ed80076a85afecfe2d905b3c52cd524 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 May 2016 14:23:03 -0700 Subject: [PATCH 040/165] TPMS: Quick implementation of "flags" column. For now, shows only for Schrader OOK packets: top (left) nibble is function code, bottom nibble has two-bit checksum. --- firmware/application/tpms_app.cpp | 16 +++++++++++++++- firmware/application/tpms_app.hpp | 1 + firmware/common/tpms_packet.cpp | 4 +++- firmware/common/tpms_packet.hpp | 13 +++++++++++-- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index d6e1ef9f..09f5fc1a 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -47,6 +47,10 @@ std::string temperature(Temperature temperature) { return to_string_dec_int(temperature.celsius(), 3); } +std::string flags(Flags flags) { + return to_string_hex(flags, 2); +} + } /* namespace format */ } /* namespace tpms */ @@ -72,16 +76,20 @@ void TPMSRecentEntry::update(const tpms::Reading& reading) { if( reading.temperature().is_valid() ) { last_temperature = reading.temperature(); } + if( reading.flags().is_valid() ) { + last_flags = reading.flags(); + } } namespace ui { -static const std::array, 5> tpms_columns { { +static const std::array, 6> tpms_columns { { { "Tp", 2 }, { "ID", 8 }, { "kPa", 3 }, { "C", 3 }, { "Cnt", 3 }, + { "Fl", 2 }, } }; template<> @@ -133,6 +141,12 @@ void RecentEntriesView::draw( line += " " + to_string_dec_uint(entry.received_count, 3); } + if( entry.last_flags.is_valid() ) { + line += " " + tpms::format::flags(entry.last_flags.value()); + } else { + line += " " " "; + } + line.resize(target_rect.width() / 8, ' '); painter.draw_string(target_rect.pos, draw_style, line); } diff --git a/firmware/application/tpms_app.hpp b/firmware/application/tpms_app.hpp index e4f00b7a..8ed0a50e 100644 --- a/firmware/application/tpms_app.hpp +++ b/firmware/application/tpms_app.hpp @@ -53,6 +53,7 @@ struct TPMSRecentEntry { Optional last_pressure; Optional last_temperature; + Optional last_flags; TPMSRecentEntry( const Key& key diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index 0fc57dd3..68b80c1e 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -74,7 +74,9 @@ Optional Packet::reading(const SignalType signal_type) const { return Reading { Reading::Type::Schrader, reader_.read(3, 24), - Pressure { static_cast(reader_.read(27, 8)) } + Pressure { static_cast(reader_.read(27, 8)) * 4 / 3 }, + { }, + Flags { (flags << 4) | checksum } }; } diff --git a/firmware/common/tpms_packet.hpp b/firmware/common/tpms_packet.hpp index 57d8d929..34c80397 100644 --- a/firmware/common/tpms_packet.hpp +++ b/firmware/common/tpms_packet.hpp @@ -37,6 +37,8 @@ using units::Pressure; namespace tpms { +using Flags = uint8_t; + enum SignalType : uint32_t { FLM = 1, Schrader = 2, @@ -92,11 +94,13 @@ public: Type type, TransponderID id, Optional pressure = { }, - Optional temperature = { } + Optional temperature = { }, + Optional flags = { } ) : type_ { type }, id_ { id }, pressure_ { pressure }, - temperature_ { temperature } + temperature_ { temperature }, + flags_ { flags } { } @@ -116,11 +120,16 @@ public: return temperature_; } + Optional flags() const { + return flags_; + } + private: Type type_ { Type::None }; TransponderID id_ { 0 }; Optional pressure_ { }; Optional temperature_ { }; + Optional flags_ { }; }; class Packet { From a4ddf786d4bc0fbf899bae8d42614220bf4c8a7e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 23 May 2016 11:12:06 -0700 Subject: [PATCH 041/165] TPMS: Move only FSK slicer and payload handler into .hpp. --- firmware/baseband/proc_tpms.cpp | 14 -------------- firmware/baseband/proc_tpms.hpp | 10 ++++++---- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index cf061d10..698394dd 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -56,17 +56,3 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { }); } } - -void TPMSProcessor::consume_symbol( - const float raw_symbol -) { - const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0; - packet_builder.execute(sliced_symbol); -} - -void TPMSProcessor::payload_handler( - const baseband::Packet& packet -) { - const TPMSPacketMessage message { tpms::SignalType::FLM, packet }; - shared_memory.application_queue.push(message); -} diff --git a/firmware/baseband/proc_tpms.hpp b/firmware/baseband/proc_tpms.hpp index fda7126e..c4044887 100644 --- a/firmware/baseband/proc_tpms.hpp +++ b/firmware/baseband/proc_tpms.hpp @@ -75,14 +75,18 @@ private: clock_recovery::ClockRecovery clock_recovery_fsk_19k2 { 38400, 19200, { 0.0555f }, - [this](const float symbol) { this->consume_symbol(symbol); } + [this](const float raw_symbol) { + const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0; + this->packet_builder.execute(sliced_symbol); + } }; PacketBuilder packet_builder { { 0b010101010101010101010101010110, 30, 1 }, { }, { 160 }, [this](const baseband::Packet& packet) { - this->payload_handler(packet); + const TPMSPacketMessage message { tpms::SignalType::FLM, packet }; + shared_memory.application_queue.push(message); } }; @@ -119,8 +123,6 @@ private: shared_memory.application_queue.push(message); } }; - void consume_symbol(const float symbol); - void payload_handler(const baseband::Packet& packet); }; #endif/*__PROC_TPMS_H__*/ From 249e6ab21e0a02bdb9e9acf4bd9768184a83ac12 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 23 May 2016 11:22:09 -0700 Subject: [PATCH 042/165] TPMS: Improve descriptiveness of pipeline component names. --- firmware/baseband/proc_tpms.cpp | 4 ++-- firmware/baseband/proc_tpms.hpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index 698394dd..83b96a1e 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -39,8 +39,8 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { feed_channel_stats(decimator_out); for(size_t i=0; i, 16> rect_taps_307k2_1t_p { { +constexpr std::array, 16> rect_taps_307k2_38k4_1t_19k2_p { { { 6.2500000000e-02f, 0.0000000000e+00f }, { 4.4194173824e-02f, 4.4194173824e-02f }, { 0.0000000000e+00f, 6.2500000000e-02f }, { -4.4194173824e-02f, 4.4194173824e-02f }, { -6.2500000000e-02f, 0.0000000000e+00f }, { -4.4194173824e-02f, -4.4194173824e-02f }, @@ -71,16 +71,16 @@ private: dsp::decimate::FIRC8xR16x24FS4Decim4 decim_0; dsp::decimate::FIRC16xR16x16Decim2 decim_1; - dsp::matched_filter::MatchedFilter mf { rect_taps_307k2_1t_p, 8 }; + dsp::matched_filter::MatchedFilter mf_38k4_1t_19k2 { rect_taps_307k2_38k4_1t_19k2_p, 8 }; clock_recovery::ClockRecovery clock_recovery_fsk_19k2 { 38400, 19200, { 0.0555f }, [this](const float raw_symbol) { const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0; - this->packet_builder.execute(sliced_symbol); + this->packet_builder_fsk_19k2_schrader.execute(sliced_symbol); } }; - PacketBuilder packet_builder { + PacketBuilder packet_builder_fsk_19k2_schrader { { 0b010101010101010101010101010110, 30, 1 }, { }, { 160 }, From 38b374506e53afb44181725993b49cfdf6433a10 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 23 May 2016 18:02:25 -0700 Subject: [PATCH 043/165] More TPMS variable/enum renaming. --- firmware/baseband/proc_tpms.cpp | 4 ++-- firmware/baseband/proc_tpms.hpp | 10 +++++----- firmware/common/tpms_packet.cpp | 6 +++--- firmware/common/tpms_packet.hpp | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index 83b96a1e..3052e4a5 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -49,10 +49,10 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { slicer_history = (slicer_history << 1) | sliced; clock_recovery_ook_8k192(slicer_history, [this](const bool symbol) { - this->packet_builder_schrader.execute(symbol); + this->packet_builder_ook_8k192_schrader.execute(symbol); }); clock_recovery_ook_8k4(slicer_history, [this](const bool symbol) { - this->packet_builder_ook_gmc.execute(symbol); + this->packet_builder_ook_8k4_schrader.execute(symbol); }); } } diff --git a/firmware/baseband/proc_tpms.hpp b/firmware/baseband/proc_tpms.hpp index 7408e148..4ceabf23 100644 --- a/firmware/baseband/proc_tpms.hpp +++ b/firmware/baseband/proc_tpms.hpp @@ -85,7 +85,7 @@ private: { }, { 160 }, [this](const baseband::Packet& packet) { - const TPMSPacketMessage message { tpms::SignalType::FLM, packet }; + const TPMSPacketMessage message { tpms::SignalType::FSK_19k2_Schrader, packet }; shared_memory.application_queue.push(message); } }; @@ -100,12 +100,12 @@ private: channel_sample_rate / 8192.0f }; - PacketBuilder packet_builder_schrader { + PacketBuilder packet_builder_ook_8k192_schrader { { 0b010101010101010101011110, 24, 0 }, { }, { 74 }, [](const baseband::Packet& packet) { - const TPMSPacketMessage message { tpms::SignalType::Schrader, packet }; + const TPMSPacketMessage message { tpms::SignalType::OOK_8k192_Schrader, packet }; shared_memory.application_queue.push(message); } }; @@ -114,12 +114,12 @@ private: channel_sample_rate / 8400.0f }; - PacketBuilder packet_builder_ook_gmc { + PacketBuilder packet_builder_ook_8k4_schrader { { 0b01010101010101010101010101100101, 32, 0 }, { }, { 192 }, [](const baseband::Packet& packet) { - const TPMSPacketMessage message { tpms::SignalType::GMC, packet }; + const TPMSPacketMessage message { tpms::SignalType::OOK_8k4_Schrader, packet }; shared_memory.application_queue.push(message); } }; diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index 68b80c1e..af95b5c7 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -34,7 +34,7 @@ ManchesterFormatted Packet::symbols_formatted() const { } Optional Packet::reading(const SignalType signal_type) const { - if( signal_type == SignalType::FLM ) { + if( signal_type == SignalType::FSK_19k2_Schrader ) { const auto length = crc_valid_length(); switch(length) { @@ -67,7 +67,7 @@ Optional Packet::reading(const SignalType signal_type) const { } } - if( signal_type == SignalType::Schrader ) { + if( signal_type == SignalType::OOK_8k192_Schrader ) { const auto flags = reader_.read(0, 3); const auto checksum = reader_.read(35, 2); @@ -80,7 +80,7 @@ Optional Packet::reading(const SignalType signal_type) const { }; } - if( signal_type == SignalType::GMC ) { + if( signal_type == SignalType::OOK_8k4_Schrader ) { return Reading { Reading::Type::GMC_96, reader_.read(20, 32), diff --git a/firmware/common/tpms_packet.hpp b/firmware/common/tpms_packet.hpp index 34c80397..85df22dc 100644 --- a/firmware/common/tpms_packet.hpp +++ b/firmware/common/tpms_packet.hpp @@ -40,9 +40,9 @@ namespace tpms { using Flags = uint8_t; enum SignalType : uint32_t { - FLM = 1, - Schrader = 2, - GMC = 3, + FSK_19k2_Schrader = 1, + OOK_8k192_Schrader = 2, + OOK_8k4_Schrader = 3, }; class TransponderID { From ff57b3c8cb3be9463d9ce296c3c31b4df1556e9f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 25 May 2016 11:32:06 -0700 Subject: [PATCH 044/165] Add Color-only constructor to ui::Rectangle widget. --- firmware/common/ui_widget.cpp | 7 +++++++ firmware/common/ui_widget.hpp | 1 + 2 files changed, 8 insertions(+) diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index abc040c3..31a71d51 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -256,6 +256,13 @@ std::string View::title() const { /* Rectangle *************************************************************/ +Rectangle::Rectangle( + Color c +) : Widget { }, + color { c } +{ +} + Rectangle::Rectangle( Rect parent_rect, Color c diff --git a/firmware/common/ui_widget.hpp b/firmware/common/ui_widget.hpp index eb45de44..2c427249 100644 --- a/firmware/common/ui_widget.hpp +++ b/firmware/common/ui_widget.hpp @@ -168,6 +168,7 @@ protected: class Rectangle : public Widget { public: + Rectangle(Color c); Rectangle(Rect parent_rect, Color c); void paint(Painter& painter) override; From 6a294e7d0e0939a0241d439d797be24a70e1632b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 25 May 2016 11:33:23 -0700 Subject: [PATCH 045/165] Shameful hack to hide RecordView when sampling_rate == 0. Switch visibility of child widgets -- UI fields/controls vs. a black rectangle. TODO: Fix painting and state management, which right now is just terrible. --- firmware/application/ui_record_view.cpp | 3 +++ firmware/application/ui_record_view.hpp | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 6922a3e4..4d385e15 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -169,12 +169,15 @@ RecordView::RecordView( buffer_count { buffer_count } { add_children({ { + &rect_background, &button_record, &text_record_filename, &text_record_dropped, &text_time_available, } }); + rect_background.set_parent_rect({ { 0, 0 }, size() }); + button_record.on_select = [this](ImageButton&) { this->toggle(); }; diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index af21987d..ddc72e9f 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -59,6 +59,12 @@ public: if( new_sampling_rate != sampling_rate ) { stop(); sampling_rate = new_sampling_rate; + + button_record.hidden(sampling_rate == 0); + text_record_filename.hidden(sampling_rate == 0); + text_record_dropped.hidden(sampling_rate == 0); + text_time_available.hidden(sampling_rate == 0); + rect_background.hidden(sampling_rate != 0); } } @@ -82,6 +88,10 @@ private: size_t sampling_rate { 0 }; SignalToken signal_token_tick_second; + Rectangle rect_background { + Color::black() + }; + ImageButton button_record { { 0 * 8, 0 * 16, 2 * 8, 1 * 16 }, &bitmap_record, From 83e4aec49c4c6a509b5ee2f91aeed17c782a76e8 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 25 May 2016 11:39:03 -0700 Subject: [PATCH 046/165] Hack to paint over last options view when none should be visible. --- firmware/application/analog_audio_app.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 44d72c42..27d2b836 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -219,8 +219,11 @@ void AnalogAudioView::set_options_widget(std::unique_ptr new_widget) { if( new_widget ) { options_widget = std::move(new_widget); - add_child(options_widget.get()); + } else { + // TODO: Lame hack to hide options view due to my bad paint/damage algorithm. + options_widget = std::make_unique(options_view_rect, style_options_group.background); } + add_child(options_widget.get()); } void AnalogAudioView::on_show_options_frequency() { From 04c472e802c8fc9481e6e79a38658b32cf5df8d7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 25 May 2016 17:58:32 -0700 Subject: [PATCH 047/165] Push SignalType inside tpms::Packet. --- firmware/application/tpms_app.cpp | 4 ++-- firmware/application/tpms_app.hpp | 6 +++--- firmware/common/tpms_packet.cpp | 8 ++++---- firmware/common/tpms_packet.hpp | 8 ++++++-- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index 09f5fc1a..91bd1750 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -191,12 +191,12 @@ void TPMSAppView::set_parent_rect(const Rect new_parent_rect) { recent_entries_view.set_parent_rect({ 0, 0, new_parent_rect.width(), new_parent_rect.height() }); } -void TPMSAppView::on_packet(const tpms::SignalType signal_type, const tpms::Packet& packet) { +void TPMSAppView::on_packet(const tpms::Packet& packet) { if( logger ) { logger->on_packet(packet, target_frequency()); } - const auto reading_opt = packet.reading(signal_type); + const auto reading_opt = packet.reading(); if( reading_opt.is_valid() ) { const auto reading = reading_opt.value(); recent.on_packet({ reading.type(), reading.id() }, reading); diff --git a/firmware/application/tpms_app.hpp b/firmware/application/tpms_app.hpp index 8ed0a50e..3ff5d1e5 100644 --- a/firmware/application/tpms_app.hpp +++ b/firmware/application/tpms_app.hpp @@ -111,8 +111,8 @@ private: Message::ID::TPMSPacket, [this](Message* const p) { const auto message = static_cast(p); - const tpms::Packet packet { message->packet }; - this->on_packet(message->signal_type, packet); + const tpms::Packet packet { message->packet, message->signal_type }; + this->on_packet(packet); } }; @@ -121,7 +121,7 @@ private: TPMSRecentEntriesView recent_entries_view { recent }; - void on_packet(const tpms::SignalType signal_type, const tpms::Packet& packet); + void on_packet(const tpms::Packet& packet); void on_show_list(); uint32_t target_frequency() const; diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index af95b5c7..5c3fd37e 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -33,8 +33,8 @@ ManchesterFormatted Packet::symbols_formatted() const { return format_manchester(decoder_); } -Optional Packet::reading(const SignalType signal_type) const { - if( signal_type == SignalType::FSK_19k2_Schrader ) { +Optional Packet::reading() const { + if( signal_type() == SignalType::FSK_19k2_Schrader ) { const auto length = crc_valid_length(); switch(length) { @@ -67,7 +67,7 @@ Optional Packet::reading(const SignalType signal_type) const { } } - if( signal_type == SignalType::OOK_8k192_Schrader ) { + if( signal_type() == SignalType::OOK_8k192_Schrader ) { const auto flags = reader_.read(0, 3); const auto checksum = reader_.read(35, 2); @@ -80,7 +80,7 @@ Optional Packet::reading(const SignalType signal_type) const { }; } - if( signal_type == SignalType::OOK_8k4_Schrader ) { + if( signal_type() == SignalType::OOK_8k4_Schrader ) { return Reading { Reading::Type::GMC_96, reader_.read(20, 32), diff --git a/firmware/common/tpms_packet.hpp b/firmware/common/tpms_packet.hpp index 85df22dc..95f3f00c 100644 --- a/firmware/common/tpms_packet.hpp +++ b/firmware/common/tpms_packet.hpp @@ -135,23 +135,27 @@ private: class Packet { public: constexpr Packet( - const baseband::Packet& packet + const baseband::Packet& packet, + const SignalType signal_type ) : packet_ { packet }, + signal_type_ { signal_type }, decoder_ { packet_, 0 }, reader_ { decoder_ } { } + SignalType signal_type() const { return signal_type_; } Timestamp received_at() const; ManchesterFormatted symbols_formatted() const; - Optional reading(const SignalType signal_type) const; + Optional reading() const; private: using Reader = FieldReader; const baseband::Packet packet_; + const SignalType signal_type_; const ManchesterDecoder decoder_; const Reader reader_; From e7aaf0e8cf168dfe42d396f08468c341fd05bb47 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 25 May 2016 17:59:14 -0700 Subject: [PATCH 048/165] Format TPMS signal type details in log file. --- firmware/application/tpms_app.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index 91bd1750..aab7004c 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -51,6 +51,15 @@ std::string flags(Flags flags) { return to_string_hex(flags, 2); } +static std::string signal_type(SignalType signal_type) { + switch(signal_type) { + case SignalType::FSK_19k2_Schrader: return "FSK 38400 19200 Schrader"; + case SignalType::OOK_8k192_Schrader: return "OOK - 8192 Schrader"; + case SignalType::OOK_8k4_Schrader: return "OOK - 8400 Schrader"; + default: return "- - - -"; + } +} + } /* namespace format */ } /* namespace tpms */ @@ -61,7 +70,7 @@ void TPMSLogger::on_packet(const tpms::Packet& packet, const uint32_t target_fre // TODO: function doesn't take uint64_t, so when >= 1<<32, weirdness will ensue! const auto tuning_frequency_str = to_string_dec_uint(target_frequency, 10); - std::string entry = tuning_frequency_str + " FSK 38.4 19.2 " + hex_formatted.data + "/" + hex_formatted.errors; + std::string entry = tuning_frequency_str + " " + tpms::format::signal_type(packet.signal_type()) + " " + hex_formatted.data + "/" + hex_formatted.errors; log_file.write_entry(packet.received_at(), entry); } From 05b55f26961d1c367ceceef5a863e8e9bb2d3ffe Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 27 May 2016 13:41:56 -0700 Subject: [PATCH 049/165] TPMS: Extract packet readers. --- firmware/common/tpms_packet.cpp | 113 +++++++++++++++++--------------- firmware/common/tpms_packet.hpp | 4 ++ 2 files changed, 63 insertions(+), 54 deletions(-) diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index 5c3fd37e..1c5b55d5 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -33,62 +33,67 @@ ManchesterFormatted Packet::symbols_formatted() const { return format_manchester(decoder_); } +Optional Packet::reading_fsk_19k2_schrader() const { + const auto length = crc_valid_length(); + + switch(length) { + case 64: + return Reading { + Reading::Type::FLM_64, + reader_.read(0, 32), + Pressure { static_cast(reader_.read(32, 8)) * 4 / 3 }, + Temperature { static_cast(reader_.read(40, 8) & 0x7f) - 50 } + }; + + case 72: + return Reading { + Reading::Type::FLM_72, + reader_.read(0, 32), + Pressure { static_cast(reader_.read(40, 8)) * 4 / 3 }, + Temperature { static_cast(reader_.read(48, 8)) - 50 } + }; + + case 80: + return Reading { + Reading::Type::FLM_80, + reader_.read(8, 32), + Pressure { static_cast(reader_.read(48, 8)) * 4 / 3 }, + Temperature { static_cast(reader_.read(56, 8)) - 50 } + }; + + default: + return { }; + } +} + +Optional Packet::reading_ook_8k192_schrader() const { + const auto flags = reader_.read(0, 3); + const auto checksum = reader_.read(35, 2); + + return Reading { + Reading::Type::Schrader, + reader_.read(3, 24), + Pressure { static_cast(reader_.read(27, 8)) * 4 / 3 }, + { }, + Flags { (flags << 4) | checksum } + }; +} + +Optional Packet::reading_ook_8k4_schrader() const { + return Reading { + Reading::Type::GMC_96, + reader_.read(20, 32), + Pressure { static_cast(reader_.read(52, 8)) } + }; +} + Optional Packet::reading() const { - if( signal_type() == SignalType::FSK_19k2_Schrader ) { - const auto length = crc_valid_length(); - - switch(length) { - case 64: - return Reading { - Reading::Type::FLM_64, - reader_.read(0, 32), - Pressure { static_cast(reader_.read(32, 8)) * 4 / 3 }, - Temperature { static_cast(reader_.read(40, 8) & 0x7f) - 50 } - }; - - case 72: - return Reading { - Reading::Type::FLM_72, - reader_.read(0, 32), - Pressure { static_cast(reader_.read(40, 8)) * 4 / 3 }, - Temperature { static_cast(reader_.read(48, 8)) - 50 } - }; - - case 80: - return Reading { - Reading::Type::FLM_80, - reader_.read(8, 32), - Pressure { static_cast(reader_.read(48, 8)) * 4 / 3 }, - Temperature { static_cast(reader_.read(56, 8)) - 50 } - }; - - default: - return { }; - } + switch( signal_type() ) { + case SignalType::FSK_19k2_Schrader: return reading_fsk_19k2_schrader(); + case SignalType::OOK_8k192_Schrader: return reading_ook_8k192_schrader(); + case SignalType::OOK_8k4_Schrader: return reading_ook_8k4_schrader(); + default: return { }; } - - if( signal_type() == SignalType::OOK_8k192_Schrader ) { - const auto flags = reader_.read(0, 3); - const auto checksum = reader_.read(35, 2); - - return Reading { - Reading::Type::Schrader, - reader_.read(3, 24), - Pressure { static_cast(reader_.read(27, 8)) * 4 / 3 }, - { }, - Flags { (flags << 4) | checksum } - }; - } - - if( signal_type() == SignalType::OOK_8k4_Schrader ) { - return Reading { - Reading::Type::GMC_96, - reader_.read(20, 32), - Pressure { static_cast(reader_.read(52, 8)) } - }; - } - - return { }; } size_t Packet::crc_valid_length() const { diff --git a/firmware/common/tpms_packet.hpp b/firmware/common/tpms_packet.hpp index 95f3f00c..4d35c962 100644 --- a/firmware/common/tpms_packet.hpp +++ b/firmware/common/tpms_packet.hpp @@ -160,6 +160,10 @@ private: const Reader reader_; + Optional reading_fsk_19k2_schrader() const; + Optional reading_ook_8k192_schrader() const; + Optional reading_ook_8k4_schrader() const; + size_t crc_valid_length() const; }; From 3d222226892d9e630e78ff4a34fbd5f088d10397 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 30 May 2016 11:23:13 -0700 Subject: [PATCH 050/165] Extract DecodedSymbol from ManchesterDecoder. --- firmware/common/manchester.cpp | 2 +- firmware/common/manchester.hpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/firmware/common/manchester.cpp b/firmware/common/manchester.cpp index 3862facc..c6d1cb9b 100644 --- a/firmware/common/manchester.cpp +++ b/firmware/common/manchester.cpp @@ -23,7 +23,7 @@ #include "string_format.hpp" -ManchesterDecoder::DecodedSymbol ManchesterDecoder::operator[](const size_t index) const { +DecodedSymbol ManchesterDecoder::operator[](const size_t index) const { const size_t encoded_index = index * 2; if( (encoded_index + 1) < packet.size() ) { const auto value = packet[encoded_index + sense]; diff --git a/firmware/common/manchester.hpp b/firmware/common/manchester.hpp index 50cae73f..c2bc820d 100644 --- a/firmware/common/manchester.hpp +++ b/firmware/common/manchester.hpp @@ -29,13 +29,13 @@ #include "baseband_packet.hpp" +struct DecodedSymbol { + uint_fast8_t value; + uint_fast8_t error; +}; + class ManchesterDecoder { public: - struct DecodedSymbol { - uint_fast8_t value; - uint_fast8_t error; - }; - constexpr ManchesterDecoder( const baseband::Packet& packet, const size_t sense = 0 @@ -54,7 +54,7 @@ private: }; template -T operator|(const T& l, const ManchesterDecoder::DecodedSymbol& r) { +T operator|(const T& l, const DecodedSymbol& r) { return l | r.value; } From a52d0fbd81c7dfff975b9c98f6567afa22f558c7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 30 May 2016 11:24:59 -0700 Subject: [PATCH 051/165] Rename format_manchester/ManchesterFormatted to "[sS]ymbols". --- firmware/common/ert_packet.cpp | 4 ++-- firmware/common/ert_packet.hpp | 2 +- firmware/common/manchester.cpp | 2 +- firmware/common/manchester.hpp | 4 ++-- firmware/common/tpms_packet.cpp | 4 ++-- firmware/common/tpms_packet.hpp | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/firmware/common/ert_packet.cpp b/firmware/common/ert_packet.cpp index 3fcf0ede..ff9e7d10 100644 --- a/firmware/common/ert_packet.cpp +++ b/firmware/common/ert_packet.cpp @@ -73,8 +73,8 @@ CommodityType Packet::commodity_type() const { return invalid_commodity_type; } -ManchesterFormatted Packet::symbols_formatted() const { - return format_manchester(decoder_); +FormattedSymbols Packet::symbols_formatted() const { + return format_symbols(decoder_); } bool Packet::crc_ok() const { diff --git a/firmware/common/ert_packet.hpp b/firmware/common/ert_packet.hpp index 0a053536..fcdf8e33 100644 --- a/firmware/common/ert_packet.hpp +++ b/firmware/common/ert_packet.hpp @@ -68,7 +68,7 @@ public: CommodityType commodity_type() const; Consumption consumption() const; - ManchesterFormatted symbols_formatted() const; + FormattedSymbols symbols_formatted() const; bool crc_ok() const; diff --git a/firmware/common/manchester.cpp b/firmware/common/manchester.cpp index c6d1cb9b..15196191 100644 --- a/firmware/common/manchester.cpp +++ b/firmware/common/manchester.cpp @@ -38,7 +38,7 @@ size_t ManchesterDecoder::symbols_count() const { return packet.size() / 2; } -ManchesterFormatted format_manchester( +FormattedSymbols format_symbols( const ManchesterDecoder& decoder ) { const size_t payload_length_decoded = decoder.symbols_count(); diff --git a/firmware/common/manchester.hpp b/firmware/common/manchester.hpp index c2bc820d..6a2376a9 100644 --- a/firmware/common/manchester.hpp +++ b/firmware/common/manchester.hpp @@ -58,12 +58,12 @@ T operator|(const T& l, const DecodedSymbol& r) { return l | r.value; } -struct ManchesterFormatted { +struct FormattedSymbols { const std::string data; const std::string errors; }; -ManchesterFormatted format_manchester( +FormattedSymbols format_symbols( const ManchesterDecoder& decoder ); diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index 1c5b55d5..8f1acffa 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -29,8 +29,8 @@ Timestamp Packet::received_at() const { return packet_.timestamp(); } -ManchesterFormatted Packet::symbols_formatted() const { - return format_manchester(decoder_); +FormattedSymbols Packet::symbols_formatted() const { + return format_symbols(decoder_); } Optional Packet::reading_fsk_19k2_schrader() const { diff --git a/firmware/common/tpms_packet.hpp b/firmware/common/tpms_packet.hpp index 4d35c962..5ee3e02a 100644 --- a/firmware/common/tpms_packet.hpp +++ b/firmware/common/tpms_packet.hpp @@ -147,7 +147,7 @@ public: SignalType signal_type() const { return signal_type_; } Timestamp received_at() const; - ManchesterFormatted symbols_formatted() const; + FormattedSymbols symbols_formatted() const; Optional reading() const; From 57767004a25d8d9ec09aae67b5d1fb33441d2aec Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 30 May 2016 11:28:22 -0700 Subject: [PATCH 052/165] TPMS: Comments, more descriptive declarations. --- firmware/baseband/proc_tpms.hpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/firmware/baseband/proc_tpms.hpp b/firmware/baseband/proc_tpms.hpp index 4ceabf23..ba3294d2 100644 --- a/firmware/baseband/proc_tpms.hpp +++ b/firmware/baseband/proc_tpms.hpp @@ -93,7 +93,7 @@ private: static constexpr float channel_rate_in = 307200.0f; static constexpr size_t channel_decimation = 8; static constexpr float channel_sample_rate = channel_rate_in / channel_decimation; - OOKSlicerMagSquaredInt ook_slicer_5sps { 5 }; + OOKSlicerMagSquaredInt ook_slicer_5sps { channel_sample_rate / 8400 + 1}; uint32_t slicer_history { 0 }; OOKClockRecovery clock_recovery_ook_8k192 { @@ -101,9 +101,13 @@ private: }; PacketBuilder packet_builder_ook_8k192_schrader { + /* Preamble: 11*2, 01*14, 11, 10 + * Payload: 37 Manchester-encoded bits + * Bit rate: 4096 Hz + */ { 0b010101010101010101011110, 24, 0 }, { }, - { 74 }, + { 37 * 2 }, [](const baseband::Packet& packet) { const TPMSPacketMessage message { tpms::SignalType::OOK_8k192_Schrader, packet }; shared_memory.application_queue.push(message); @@ -115,9 +119,13 @@ private: }; PacketBuilder packet_builder_ook_8k4_schrader { + /* Preamble: 01*40, 01, 10, 01, 01 + * Payload: 76 Manchester-encoded bits + * Bit rate: 4200 Hz + */ { 0b01010101010101010101010101100101, 32, 0 }, { }, - { 192 }, + { 76 * 2 }, [](const baseband::Packet& packet) { const TPMSPacketMessage message { tpms::SignalType::OOK_8k4_Schrader, packet }; shared_memory.application_queue.push(message); From 36eefa46e7cce3183096f65e87906d39a72d4cfb Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 1 Jun 2016 15:20:23 -0700 Subject: [PATCH 053/165] Improve OOK phase advance algorithm. Now independent of samples/symbol, adjusts up to 1/8 of a cycle per symbol. --- firmware/baseband/ook.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firmware/baseband/ook.hpp b/firmware/baseband/ook.hpp index 27333922..2453f2f4 100644 --- a/firmware/baseband/ook.hpp +++ b/firmware/baseband/ook.hpp @@ -70,6 +70,7 @@ public: constexpr OOKClockRecovery( const float samples_per_symbol ) : symbol_phase_inc_nominal { static_cast(std::round((1ULL << 32) / samples_per_symbol)) }, + symbol_phase_inc_k { symbol_phase_inc_nominal * (2.0f / 8.0f) / samples_per_symbol }, phase_detector { samples_per_symbol }, phase_accumulator { symbol_phase_inc_nominal } { @@ -79,13 +80,14 @@ public: void operator()(const uint32_t slicer_history, SymbolHandler symbol_handler) { if( phase_accumulator() ) { const auto detector_result = phase_detector(slicer_history); - phase_accumulator.set_inc(symbol_phase_inc_nominal + detector_result.error * (symbol_phase_inc_nominal >> 3)); + phase_accumulator.set_inc(symbol_phase_inc_nominal + detector_result.error * symbol_phase_inc_k); symbol_handler(detector_result.symbol); } } private: const uint32_t symbol_phase_inc_nominal; + const uint32_t symbol_phase_inc_k; PhaseDetectorEarlyLateGate phase_detector; PhaseAccumulator phase_accumulator; }; From 47347905185a2393042f593ca3263e6e32f7c625 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 1 Jun 2016 15:22:21 -0700 Subject: [PATCH 054/165] Rework phase detector. Simplify calculation of gate masks. Use entire symbol period to compute symbol value. Correct error sign based on symbol value. --- firmware/baseband/phase_detector.hpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/firmware/baseband/phase_detector.hpp b/firmware/baseband/phase_detector.hpp index 89cf4b5c..4e6f0d34 100644 --- a/firmware/baseband/phase_detector.hpp +++ b/firmware/baseband/phase_detector.hpp @@ -39,30 +39,32 @@ public: }; constexpr PhaseDetectorEarlyLateGate( - const float samples_per_symbol - ) : late_mask { (1U << static_cast(std::ceil(samples_per_symbol / 2))) - 1 }, - early_mask { late_mask << static_cast(std::floor(samples_per_symbol / 2)) }, - sample_bit { static_cast(std::floor(samples_per_symbol / 2)) } + const size_t samples_per_symbol + ) : sample_threshold { samples_per_symbol / 2 }, + late_mask { (1UL << sample_threshold) - 1UL }, + early_mask { late_mask << sample_threshold } { } result_t operator()(const history_t symbol_history) const { + static_assert(sizeof(history_t) == sizeof(unsigned long), "popcountl size mismatch"); + // history = ...0111, early // history = ...1110, late - const symbol_t symbol = (symbol_history >> sample_bit) & 1; - const int late_side = __builtin_popcount(symbol_history & late_mask); - const int early_side = __builtin_popcount(symbol_history & early_mask); - const int lateness = late_side - early_side; - const int direction = lateness; //std::min(std::max(lateness, -1), 1); - const error_t error = direction; + const size_t late_side = __builtin_popcountl(symbol_history & late_mask); + const size_t early_side = __builtin_popcountl(symbol_history & early_mask); + const size_t total_count = late_side + early_side; + const auto lateness = static_cast(late_side) - static_cast(early_side); + const symbol_t symbol = (total_count >= sample_threshold); + const error_t error = symbol ? -lateness : lateness; return { symbol, error }; } private: + const size_t sample_threshold; const history_t late_mask; const history_t early_mask; - const size_t sample_bit; }; #endif/*__PHASE_DETECTOR_HPP__*/ From 9628815da7c9079b45fe4e88b212c2d5d5399585 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 2 Jun 2016 22:22:22 -0700 Subject: [PATCH 055/165] TPMS: Validate checksum for the OOK 8k4 Schrader variant. --- firmware/common/tpms_packet.cpp | 38 ++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index 8f1acffa..55e80932 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -80,11 +80,39 @@ Optional Packet::reading_ook_8k192_schrader() const { } Optional Packet::reading_ook_8k4_schrader() const { - return Reading { - Reading::Type::GMC_96, - reader_.read(20, 32), - Pressure { static_cast(reader_.read(52, 8)) } - }; + /* + * Preamble: 01*40 + * System ID: 01100101, ??*20 (not really sure what this data is) + * ID: 32 Manchester symbols + * Value: 8 Manchester symbols (temperature?) + * Value: 8 Manchester symbols (pressure?) + * Checksum: 8 Manchester symbols (uint8_t sum of bytes starting with system ID) + */ + /* NOTE: First four bits of packet are consumed in preamble detection. + * Those bits assumed to be 0b0100", which may not be entirely true... + */ + constexpr uint8_t first_nibble = 0x4; + const auto system_id = (first_nibble << 20) | reader_.read(0, 20); + const auto id = reader_.read(20, 32); + const auto value_0 = reader_.read(52, 8); + const auto value_1 = reader_.read(60, 8); + const auto checksum = reader_.read(68, 8); + + uint8_t checksum_calculated = (first_nibble << 4) | reader_.read(0, 4); + for(size_t i=4; i<68; i+=8) { + checksum_calculated += reader_.read(i, 8); + } + + if( checksum_calculated == checksum ) { + return Reading { + Reading::Type::GMC_96, + id, + Pressure { static_cast(value_1) * 4 / 3 }, + Temperature { static_cast(value_0) - 50 } + }; + } else { + return { }; + } } Optional Packet::reading() const { From a475daeeea690374b2033fba5ed40993168c1eee Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 2 Jun 2016 23:09:55 -0700 Subject: [PATCH 056/165] TPMS: Validate checksum for OOK 8k192 Schrader. --- firmware/common/tpms_packet.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index 55e80932..0bc3064b 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -67,16 +67,32 @@ Optional Packet::reading_fsk_19k2_schrader() const { } Optional Packet::reading_ook_8k192_schrader() const { + /* + * Preamble: 11*2, 01*14, 11, 10 + * Function code: 3 Manchester symbols + * ID: 24 Manchester symbols (one variant seen with 21 symbols?) + * Pressure: 8 Manchester symbols + * Checksum: 2 Manchester symbols (2 LSBs of sum incl this field == 3) + */ const auto flags = reader_.read(0, 3); const auto checksum = reader_.read(35, 2); - return Reading { - Reading::Type::Schrader, - reader_.read(3, 24), - Pressure { static_cast(reader_.read(27, 8)) * 4 / 3 }, - { }, - Flags { (flags << 4) | checksum } - }; + uint32_t checksum_calculated = reader_.read(0, 1); + for(size_t i=1; i<37; i+=2) { + checksum_calculated += reader_.read(i, 2); + } + + if( (checksum_calculated & 3) == 3 ) { + return Reading { + Reading::Type::Schrader, + reader_.read(3, 24), + Pressure { static_cast(reader_.read(27, 8)) * 4 / 3 }, + { }, + Flags { (flags << 4) | checksum } + }; + } else { + return { }; + } } Optional Packet::reading_ook_8k4_schrader() const { From a0e7fdf90be9bd77c4d4ca53885ebad047268559 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 6 Jun 2016 09:50:48 -0700 Subject: [PATCH 057/165] TPMS: Add gain controls. --- firmware/application/tpms_app.cpp | 23 +++++++++++++++++++++-- firmware/application/tpms_app.hpp | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index aab7004c..795a3ad0 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -23,6 +23,9 @@ #include "baseband_api.hpp" +#include "portapack.hpp" +using namespace portapack; + #include "string_format.hpp" #include "utility.hpp" @@ -162,15 +165,31 @@ void RecentEntriesView::draw( TPMSAppView::TPMSAppView(NavigationView&) { add_children({ { + &rssi, + &channel, + &field_lna, + &field_vga, &recent_entries_view, } }); + field_lna.set_value(receiver_model.lna()); + field_lna.on_change = [this](int32_t v_db) { + receiver_model.set_lna(v_db); + }; + + field_vga.set_value(receiver_model.vga()); + field_vga.on_change = [this](int32_t v_db) { + receiver_model.set_vga(v_db); + }; + radio::enable({ tuning_frequency(), sampling_rate, baseband_bandwidth, rf::Direction::Receive, - false, 32, 32, + false, + static_cast(receiver_model.lna()), + static_cast(receiver_model.vga()), 1, }); @@ -197,7 +216,7 @@ void TPMSAppView::focus() { void TPMSAppView::set_parent_rect(const Rect new_parent_rect) { View::set_parent_rect(new_parent_rect); - recent_entries_view.set_parent_rect({ 0, 0, new_parent_rect.width(), new_parent_rect.height() }); + recent_entries_view.set_parent_rect({ 0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height }); } void TPMSAppView::on_packet(const tpms::Packet& packet) { diff --git a/firmware/application/tpms_app.hpp b/firmware/application/tpms_app.hpp index 3ff5d1e5..8396deb8 100644 --- a/firmware/application/tpms_app.hpp +++ b/firmware/application/tpms_app.hpp @@ -24,6 +24,9 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" +#include "ui_receiver.hpp" +#include "ui_rssi.hpp" +#include "ui_channel.hpp" #include "event_m0.hpp" @@ -116,6 +119,24 @@ private: } }; + static constexpr ui::Dim header_height = 2 * 16; + + RSSI rssi { + { 21 * 8, 0, 6 * 8, 4 }, + }; + + Channel channel { + { 21 * 8, 5, 6 * 8, 4 }, + }; + + LNAGainField field_lna { + { 15 * 8, 0 * 16 } + }; + + VGAGainField field_vga { + { 18 * 8, 0 * 16 } + }; + TPMSRecentEntries recent; std::unique_ptr logger; From 5ee035fbb3f71be69734027669f4081d450c3734 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 6 Jun 2016 10:13:36 -0700 Subject: [PATCH 058/165] Move RF amp control code into new class. --- firmware/application/analog_audio_app.cpp | 9 ------- firmware/application/analog_audio_app.hpp | 1 - firmware/application/ui_receiver.cpp | 33 +++++++++++++---------- firmware/application/ui_receiver.hpp | 17 +++++------- 4 files changed, 25 insertions(+), 35 deletions(-) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 27d2b836..9edf96a6 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -182,10 +182,6 @@ void AnalogAudioView::on_baseband_bandwidth_changed(uint32_t bandwidth_hz) { receiver_model.set_baseband_bandwidth(bandwidth_hz); } -void AnalogAudioView::on_rf_amp_changed(bool v) { - receiver_model.set_rf_amp(v); -} - void AnalogAudioView::on_lna_changed(int32_t v_db) { receiver_model.set_lna(v_db); } @@ -245,11 +241,6 @@ void AnalogAudioView::on_show_options_frequency() { void AnalogAudioView::on_show_options_rf_gain() { auto widget = std::make_unique(options_view_rect, &style_options_group); - widget->set_rf_amp(receiver_model.rf_amp()); - widget->on_change_rf_amp = [this](bool enable) { - this->on_rf_amp_changed(enable); - }; - set_options_widget(std::move(widget)); field_lna.set_style(&style_options_group); } diff --git a/firmware/application/analog_audio_app.hpp b/firmware/application/analog_audio_app.hpp index 0da7a7ad..db9b9f28 100644 --- a/firmware/application/analog_audio_app.hpp +++ b/firmware/application/analog_audio_app.hpp @@ -150,7 +150,6 @@ private: void on_tuning_frequency_changed(rf::Frequency f); void on_baseband_bandwidth_changed(uint32_t bandwidth_hz); - void on_rf_amp_changed(bool v); void on_lna_changed(int32_t v_db); void on_vga_changed(int32_t v_db); void on_modulation_changed(const ReceiverModel::Mode modulation); diff --git a/firmware/application/ui_receiver.cpp b/firmware/application/ui_receiver.cpp index 0494d47c..0198a171 100644 --- a/firmware/application/ui_receiver.cpp +++ b/firmware/application/ui_receiver.cpp @@ -269,6 +269,25 @@ void FrequencyOptionsView::on_reference_ppm_correction_changed(int32_t v) { } } +/* RFAmpField ************************************************************/ + +RFAmpField::RFAmpField( + Point parent_pos +) : NumberField { + parent_pos, + 1, + { 0, 1 }, + 1, + ' ', + } +{ + set_value(receiver_model.rf_amp()); + + on_change = [](int32_t v) { + receiver_model.set_rf_amp(v); + }; +} + /* RadioGainOptionsView **************************************************/ RadioGainOptionsView::RadioGainOptionsView( @@ -282,20 +301,6 @@ RadioGainOptionsView::RadioGainOptionsView( &label_rf_amp, &field_rf_amp, } }); - - field_rf_amp.on_change = [this](int32_t v) { - this->on_rf_amp_changed(v); - }; -} - -void RadioGainOptionsView::set_rf_amp(int32_t v_db) { - field_rf_amp.set_value(v_db); -} - -void RadioGainOptionsView::on_rf_amp_changed(bool enable) { - if( on_change_rf_amp ) { - on_change_rf_amp(enable); - } } /* LNAGainField **********************************************************/ diff --git a/firmware/application/ui_receiver.hpp b/firmware/application/ui_receiver.hpp index 6aff9dda..12ab961c 100644 --- a/firmware/application/ui_receiver.hpp +++ b/firmware/application/ui_receiver.hpp @@ -281,29 +281,24 @@ private: }; }; +class RFAmpField : public NumberField { +public: + RFAmpField(Point parent_pos); +}; + class RadioGainOptionsView : public View { public: - std::function on_change_rf_amp; - RadioGainOptionsView(const Rect parent_rect, const Style* const style); - void set_rf_amp(int32_t v_db); - private: Text label_rf_amp { { 0 * 8, 0 * 16, 3 * 8, 1 * 16 }, "Amp" }; - NumberField field_rf_amp { + RFAmpField field_rf_amp { { 4 * 8, 0 * 16}, - 1, - { 0, 1 }, - 1, - ' ', }; - - void on_rf_amp_changed(bool enable); }; class LNAGainField : public NumberField { From 9190fe7e4f7a711a6fbba7b68299dfa1b4d0af99 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 6 Jun 2016 10:27:33 -0700 Subject: [PATCH 059/165] Move common code to LNA/VGA field widgets. --- firmware/application/analog_audio_app.cpp | 17 ----------------- firmware/application/analog_audio_app.hpp | 2 -- firmware/application/capture_app.cpp | 18 ------------------ firmware/application/capture_app.hpp | 2 -- firmware/application/tpms_app.cpp | 10 ---------- firmware/application/ui_receiver.cpp | 10 ++++++++++ 6 files changed, 10 insertions(+), 49 deletions(-) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 9edf96a6..4145d2c4 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -108,19 +108,10 @@ AnalogAudioView::AnalogAudioView( this->on_show_options_frequency(); }; - field_lna.set_value(receiver_model.lna()); - field_lna.on_change = [this](int32_t v) { - this->on_lna_changed(v); - }; - field_lna.on_show_options = [this]() { this->on_show_options_rf_gain(); }; - field_vga.set_value(receiver_model.vga()); - field_vga.on_change = [this](int32_t v_db) { - this->on_vga_changed(v_db); - }; field_vga.on_show_options = [this]() { this->on_show_options_rf_gain(); }; @@ -182,14 +173,6 @@ void AnalogAudioView::on_baseband_bandwidth_changed(uint32_t bandwidth_hz) { receiver_model.set_baseband_bandwidth(bandwidth_hz); } -void AnalogAudioView::on_lna_changed(int32_t v_db) { - receiver_model.set_lna(v_db); -} - -void AnalogAudioView::on_vga_changed(int32_t v_db) { - receiver_model.set_vga(v_db); -} - void AnalogAudioView::on_modulation_changed(const ReceiverModel::Mode modulation) { // TODO: Terrible kludge because widget system doesn't notify Waterfall that // it's being shown or hidden. diff --git a/firmware/application/analog_audio_app.hpp b/firmware/application/analog_audio_app.hpp index db9b9f28..a91e8059 100644 --- a/firmware/application/analog_audio_app.hpp +++ b/firmware/application/analog_audio_app.hpp @@ -150,8 +150,6 @@ private: void on_tuning_frequency_changed(rf::Frequency f); void on_baseband_bandwidth_changed(uint32_t bandwidth_hz); - void on_lna_changed(int32_t v_db); - void on_vga_changed(int32_t v_db); void on_modulation_changed(const ReceiverModel::Mode modulation); void on_show_options_frequency(); void on_show_options_rf_gain(); diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index cff3bf0b..4ad9d823 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -51,16 +51,6 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { }; }; - field_lna.set_value(receiver_model.lna()); - field_lna.on_change = [this](int32_t v) { - this->on_lna_changed(v); - }; - - field_vga.set_value(receiver_model.vga()); - field_vga.on_change = [this](int32_t v_db) { - this->on_vga_changed(v_db); - }; - receiver_model.set_baseband_configuration({ .mode = toUType(ReceiverModel::Mode::Capture), .sampling_rate = sampling_rate, @@ -101,12 +91,4 @@ void CaptureAppView::on_tuning_frequency_changed(rf::Frequency f) { receiver_model.set_tuning_frequency(f); } -void CaptureAppView::on_lna_changed(int32_t v_db) { - receiver_model.set_lna(v_db); -} - -void CaptureAppView::on_vga_changed(int32_t v_db) { - receiver_model.set_vga(v_db); -} - } /* namespace ui */ diff --git a/firmware/application/capture_app.hpp b/firmware/application/capture_app.hpp index 6ece4b89..14d48434 100644 --- a/firmware/application/capture_app.hpp +++ b/firmware/application/capture_app.hpp @@ -53,8 +53,6 @@ private: static constexpr uint32_t baseband_bandwidth = 2500000; void on_tuning_frequency_changed(rf::Frequency f); - void on_lna_changed(int32_t v_db); - void on_vga_changed(int32_t v_db); RSSI rssi { { 21 * 8, 0, 6 * 8, 4 }, diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index 795a3ad0..5462db6e 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -172,16 +172,6 @@ TPMSAppView::TPMSAppView(NavigationView&) { &recent_entries_view, } }); - field_lna.set_value(receiver_model.lna()); - field_lna.on_change = [this](int32_t v_db) { - receiver_model.set_lna(v_db); - }; - - field_vga.set_value(receiver_model.vga()); - field_vga.on_change = [this](int32_t v_db) { - receiver_model.set_vga(v_db); - }; - radio::enable({ tuning_frequency(), sampling_rate, diff --git a/firmware/application/ui_receiver.cpp b/firmware/application/ui_receiver.cpp index 0198a171..479d4468 100644 --- a/firmware/application/ui_receiver.cpp +++ b/firmware/application/ui_receiver.cpp @@ -314,6 +314,11 @@ LNAGainField::LNAGainField( ' ', } { + set_value(receiver_model.lna()); + + on_change = [](int32_t v) { + receiver_model.set_lna(v); + }; } void LNAGainField::on_focus() { @@ -334,6 +339,11 @@ VGAGainField::VGAGainField( ' ', } { + set_value(receiver_model.vga()); + + on_change = [](int32_t v) { + receiver_model.set_vga(v); + }; } void VGAGainField::on_focus() { From 0da48b099c7e7faaf5ac9855fe25fd10b2eb8aba Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 6 Jun 2016 10:34:39 -0700 Subject: [PATCH 060/165] Add RF amp field to TPMS, capture modes. --- firmware/application/capture_app.cpp | 1 + firmware/application/capture_app.hpp | 6 +++++- firmware/application/tpms_app.cpp | 1 + firmware/application/tpms_app.hpp | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 4ad9d823..218b0583 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -31,6 +31,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { &rssi, &channel, &field_frequency, + &field_rf_amp, &field_lna, &field_vga, &record_view, diff --git a/firmware/application/capture_app.hpp b/firmware/application/capture_app.hpp index 14d48434..985bdb8d 100644 --- a/firmware/application/capture_app.hpp +++ b/firmware/application/capture_app.hpp @@ -63,7 +63,11 @@ private: }; FrequencyField field_frequency { - { 5 * 8, 0 * 16 }, + { 3 * 8, 0 * 16 }, + }; + + RFAmpField field_rf_amp { + { 13 * 8, 0 * 16 } }; LNAGainField field_lna { diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index 5462db6e..aa03ba68 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -167,6 +167,7 @@ TPMSAppView::TPMSAppView(NavigationView&) { add_children({ { &rssi, &channel, + &field_rf_amp, &field_lna, &field_vga, &recent_entries_view, diff --git a/firmware/application/tpms_app.hpp b/firmware/application/tpms_app.hpp index 8396deb8..707208c7 100644 --- a/firmware/application/tpms_app.hpp +++ b/firmware/application/tpms_app.hpp @@ -129,6 +129,10 @@ private: { 21 * 8, 5, 6 * 8, 4 }, }; + RFAmpField field_rf_amp { + { 13 * 8, 0 * 16 } + }; + LNAGainField field_lna { { 15 * 8, 0 * 16 } }; From dbc2a5c9eaf6c9961c6bf0de29c88f856b125ca5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 19 Jun 2016 11:20:45 -0700 Subject: [PATCH 061/165] Hide CaptureThread event mask, only used internally. --- firmware/application/capture_thread.cpp | 6 +++--- firmware/application/capture_thread.hpp | 2 ++ firmware/application/event_m0.hpp | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index 50ed7a27..726076bc 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -92,7 +92,7 @@ CaptureThread::CaptureThread( CaptureThread::~CaptureThread() { if( thread ) { chThdTerminate(thread); - chEvtSignal(thread, EVT_MASK_CAPTURE_THREAD); + chEvtSignal(thread, event_mask_loop_wake); chThdWait(thread); thread = nullptr; } @@ -108,7 +108,7 @@ void CaptureThread::check_fifo_isr() { const auto fifo = StreamOutput::fifo_buffers_full; if( fifo ) { if( !fifo->is_empty() ) { - chEvtSignalI(thread, EVT_MASK_CAPTURE_THREAD); + chEvtSignalI(thread, event_mask_loop_wake); } } } @@ -125,7 +125,7 @@ Optional CaptureThread::run() { } stream.release_buffer(buffer); } else { - chEvtWaitAny(EVT_MASK_CAPTURE_THREAD); + chEvtWaitAny(event_mask_loop_wake); } } diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index 6842982c..2b35423e 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -57,6 +57,8 @@ public: static void check_fifo_isr(); private: + static constexpr auto event_mask_loop_wake = EVENT_MASK(0); + CaptureConfig config; std::unique_ptr writer; Optional last_error; diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 6c716488..0344905d 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -44,7 +44,6 @@ constexpr auto EVT_MASK_SWITCHES = EVENT_MASK(3); constexpr auto EVT_MASK_ENCODER = EVENT_MASK(4); constexpr auto EVT_MASK_TOUCH = EVENT_MASK(5); constexpr auto EVT_MASK_APPLICATION = EVENT_MASK(6); -constexpr auto EVT_MASK_CAPTURE_THREAD = EVENT_MASK(7); class EventDispatcher { public: From f731366248a6800c7bcf7c5abadced857aa37722 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 19 Jun 2016 11:41:38 -0700 Subject: [PATCH 062/165] Hide some M0 EventDispatcher event masks. --- firmware/application/event_m0.hpp | 15 ++++++++++++--- firmware/application/irq_lcd_frame.cpp | 2 +- firmware/application/irq_rtc.cpp | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 0344905d..5b3b2fd2 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -38,12 +38,9 @@ #include -constexpr auto EVT_MASK_RTC_TICK = EVENT_MASK(0); -constexpr auto EVT_MASK_LCD_FRAME_SYNC = EVENT_MASK(1); constexpr auto EVT_MASK_SWITCHES = EVENT_MASK(3); constexpr auto EVT_MASK_ENCODER = EVENT_MASK(4); constexpr auto EVT_MASK_TOUCH = EVENT_MASK(5); -constexpr auto EVT_MASK_APPLICATION = EVENT_MASK(6); class EventDispatcher { public: @@ -63,6 +60,14 @@ public: } } + static inline void event_isr_rtc_tick() { + events_flag_isr(EVT_MASK_RTC_TICK); + } + + static inline void event_isr_lcd_frame_sync() { + events_flag_isr(EVT_MASK_LCD_FRAME_SYNC); + } + static inline void events_flag(const eventmask_t events) { if( thread_event_loop ) { chEvtSignal(thread_event_loop, events); @@ -80,6 +85,10 @@ public: } private: + static constexpr auto EVT_MASK_RTC_TICK = EVENT_MASK(0); + static constexpr auto EVT_MASK_LCD_FRAME_SYNC = EVENT_MASK(1); + static constexpr auto EVT_MASK_APPLICATION = EVENT_MASK(6); + static MessageHandlerMap message_map_; static Thread* thread_event_loop; diff --git a/firmware/application/irq_lcd_frame.cpp b/firmware/application/irq_lcd_frame.cpp index 585feb1f..d6a1c1bd 100644 --- a/firmware/application/irq_lcd_frame.cpp +++ b/firmware/application/irq_lcd_frame.cpp @@ -54,7 +54,7 @@ CH_IRQ_HANDLER(PIN_INT4_IRQHandler) { CH_IRQ_PROLOGUE(); chSysLockFromIsr(); - EventDispatcher::events_flag_isr(EVT_MASK_LCD_FRAME_SYNC); + EventDispatcher::event_isr_lcd_frame_sync(); chSysUnlockFromIsr(); LPC_GPIO_INT->IST = (1U << 4); diff --git a/firmware/application/irq_rtc.cpp b/firmware/application/irq_rtc.cpp index 332f1b3e..f9c047bf 100644 --- a/firmware/application/irq_rtc.cpp +++ b/firmware/application/irq_rtc.cpp @@ -39,7 +39,7 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { CH_IRQ_PROLOGUE(); chSysLockFromIsr(); - EventDispatcher::events_flag_isr(EVT_MASK_RTC_TICK); + EventDispatcher::event_isr_rtc_tick(); chSysUnlockFromIsr(); rtc::interrupt::clear_all(); From 6bd191349a7a1b9f70c64c0ddf19d8091596122d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 19 Jun 2016 22:56:06 -0700 Subject: [PATCH 063/165] Hide MessageHandlerMap. Definitely didn't belong in message.hpp, saw no reason to expose it outside translation unit (.cpp file). --- firmware/application/event_m0.cpp | 43 +++++++++++++++++++++++--- firmware/application/event_m0.hpp | 7 ++--- firmware/application/ui_navigation.cpp | 2 +- firmware/common/message.hpp | 29 ----------------- 4 files changed, 41 insertions(+), 40 deletions(-) diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index f0f0bdb4..33c81ad3 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -57,7 +57,36 @@ CH_IRQ_HANDLER(M4Core_IRQHandler) { } -MessageHandlerMap EventDispatcher::message_map_; +class MessageHandlerMap { +public: + using MessageHandler = std::function; + + void register_handler(const Message::ID id, MessageHandler&& handler) { + if( map_[toUType(id)] != nullptr ) { + chDbgPanic("MsgDblReg"); + } + map_[toUType(id)] = std::move(handler); + } + + void unregister_handler(const Message::ID id) { + map_[toUType(id)] = nullptr; + } + + void send(Message* const message) { + if( message->id < Message::ID::MAX ) { + auto& fn = map_[toUType(message->id)]; + if( fn ) { + fn(message); + } + } + } + +private: + using MapType = std::array; + MapType map_; +}; + +static MessageHandlerMap message_map; Thread* EventDispatcher::thread_event_loop = nullptr; EventDispatcher::EventDispatcher( @@ -90,6 +119,10 @@ void EventDispatcher::request_stop() { is_running = false; } +void EventDispatcher::send_message(Message* const message) { + message_map.send(message); +} + void EventDispatcher::set_display_sleep(const bool sleep) { // TODO: Distribute display sleep message more broadly, shut down data generation // on baseband side, since all that data is being discarded during sleep. @@ -137,7 +170,7 @@ void EventDispatcher::dispatch(const eventmask_t events) { void EventDispatcher::handle_application_queue() { shared_memory.application_queue.handle([](Message* const message) { - message_map().send(message); + message_map.send(message); }); } @@ -193,7 +226,7 @@ void EventDispatcher::on_touch_event(ui::TouchEvent event) { void EventDispatcher::handle_lcd_frame_sync() { DisplayFrameSyncMessage message; - message_map().send(&message); + message_map.send(&message); painter.paint_widget_tree(top_widget); } @@ -262,9 +295,9 @@ MessageHandlerRegistration::MessageHandlerRegistration( MessageHandlerMap::MessageHandler&& callback ) : message_id { message_id } { - EventDispatcher::message_map().register_handler(message_id, std::move(callback)); + message_map.register_handler(message_id, std::move(callback)); } MessageHandlerRegistration::~MessageHandlerRegistration() { - EventDispatcher::message_map().unregister_handler(message_id); + message_map.unregister_handler(message_id); } diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 5b3b2fd2..cdf73e84 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -80,16 +80,13 @@ public: } } - static MessageHandlerMap& message_map() { - return message_map_; - } + static void send_message(Message* const message); private: static constexpr auto EVT_MASK_RTC_TICK = EVENT_MASK(0); static constexpr auto EVT_MASK_LCD_FRAME_SYNC = EVENT_MASK(1); static constexpr auto EVT_MASK_APPLICATION = EVENT_MASK(6); - static MessageHandlerMap message_map_; static Thread* thread_event_loop; touch::Manager touch_manager; @@ -128,7 +125,7 @@ class MessageHandlerRegistration { public: MessageHandlerRegistration( const Message::ID message_id, - MessageHandlerMap::MessageHandler&& callback + std::function&& callback ); ~MessageHandlerRegistration(); diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index bb554d05..59de5a23 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -63,7 +63,7 @@ SystemStatusView::SystemStatusView() { button_sleep.on_select = [this](ImageButton&) { DisplaySleepMessage message; - EventDispatcher::message_map().send(&message); + EventDispatcher::send_message(&message); }; } diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index bc94fe12..640cd1d0 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -494,33 +494,4 @@ public: CaptureConfig* const config; }; -class MessageHandlerMap { -public: - using MessageHandler = std::function; - - void register_handler(const Message::ID id, MessageHandler&& handler) { - if( map_[toUType(id)] != nullptr ) { - chDbgPanic("MsgDblReg"); - } - map_[toUType(id)] = std::move(handler); - } - - void unregister_handler(const Message::ID id) { - map_[toUType(id)] = nullptr; - } - - void send(Message* const message) { - if( message->id < Message::ID::MAX ) { - auto& fn = map_[toUType(message->id)]; - if( fn ) { - fn(message); - } - } - } - -private: - using MapType = std::array; - MapType map_; -}; - #endif/*__MESSAGE_H__*/ From 420adea1802d76cfcd48b37f2f2659c3ad727d95 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 20 Jun 2016 10:52:59 -0700 Subject: [PATCH 064/165] Move capture start/stop into baseband API. Hide more calls to baseband/shared memory. --- firmware/application/baseband_api.cpp | 12 ++++++++++++ firmware/application/baseband_api.hpp | 3 +++ firmware/application/capture_thread.cpp | 10 +++------- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 3c87682b..e3acad31 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -102,4 +102,16 @@ void spectrum_streaming_stop() { ); } +void capture_start(CaptureConfig* const config) { + shared_memory.baseband_queue.push_and_wait( + CaptureConfigMessage { config } + ); +} + +void capture_stop() { + shared_memory.baseband_queue.push_and_wait( + CaptureConfigMessage { nullptr } + ); +} + } /* namespace baseband */ diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index 15959142..b029e2ec 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -58,6 +58,9 @@ void shutdown(); void spectrum_streaming_start(); void spectrum_streaming_stop(); +void capture_start(CaptureConfig* const config); +void capture_stop(); + } /* namespace baseband */ #endif/*__BASEBAND_API_H__*/ diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index 726076bc..8fab7940 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -21,7 +21,7 @@ #include "capture_thread.hpp" -#include "portapack_shared_memory.hpp" +#include "baseband_api.hpp" // StreamOutput /////////////////////////////////////////////////////////// @@ -59,9 +59,7 @@ StreamOutput::StreamOutput( CaptureConfig* const config ) : config { config } { - shared_memory.baseband_queue.push_and_wait( - CaptureConfigMessage { config } - ); + baseband::capture_start(config); fifo_buffers_empty = config->fifo_buffers_empty; fifo_buffers_full = config->fifo_buffers_full; } @@ -69,9 +67,7 @@ StreamOutput::StreamOutput( StreamOutput::~StreamOutput() { fifo_buffers_full = nullptr; fifo_buffers_empty = nullptr; - shared_memory.baseband_queue.push_and_wait( - CaptureConfigMessage { nullptr } - ); + baseband::capture_stop(); } // CaptureThread ////////////////////////////////////////////////////////// From c990963298cf7670595b95bad0019852014cb716 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 10:54:13 -0700 Subject: [PATCH 065/165] Expose filesystem_error code. --- firmware/application/file.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index 6d3453e6..7504fb93 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -56,6 +56,10 @@ struct filesystem_error { { } + uint32_t code() const { + return err; + } + std::string what() const; private: From 9f95eb90a306c507b0a3851e8ca91ab55fddfb91 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 10:55:24 -0700 Subject: [PATCH 066/165] Shrink baseband queue size, 2^12 -> 2^11. --- firmware/common/portapack_shared_memory.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/portapack_shared_memory.hpp b/firmware/common/portapack_shared_memory.hpp index b7b97f39..df8b68d7 100644 --- a/firmware/common/portapack_shared_memory.hpp +++ b/firmware/common/portapack_shared_memory.hpp @@ -33,7 +33,7 @@ struct TouchADCFrame { /* NOTE: These structures must be located in the same location in both M4 and M0 binaries */ struct SharedMemory { - static constexpr size_t baseband_queue_k = 12; + static constexpr size_t baseband_queue_k = 11; static constexpr size_t application_queue_k = 11; MessageQueue baseband_queue; From 702361680809bb9238eee101bc4403fbde3c3065 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 10:56:00 -0700 Subject: [PATCH 067/165] Move MessageQueue locations in SharedMemory structure. --- firmware/common/portapack_shared_memory.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/common/portapack_shared_memory.hpp b/firmware/common/portapack_shared_memory.hpp index df8b68d7..3310f033 100644 --- a/firmware/common/portapack_shared_memory.hpp +++ b/firmware/common/portapack_shared_memory.hpp @@ -36,10 +36,10 @@ struct SharedMemory { static constexpr size_t baseband_queue_k = 11; static constexpr size_t application_queue_k = 11; - MessageQueue baseband_queue; uint8_t baseband_queue_data[1 << baseband_queue_k]; - MessageQueue application_queue; uint8_t application_queue_data[1 << application_queue_k]; + MessageQueue baseband_queue; + MessageQueue application_queue; // TODO: M0 should directly configure and control DMA channel that is // acquiring ADC samples. From dbe735233abda8a179dc56843426586f9928ccab Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 10:57:44 -0700 Subject: [PATCH 068/165] Add app-local MessageQueue. --- firmware/application/event_m0.cpp | 13 +++++++++++++ firmware/application/event_m0.hpp | 2 ++ firmware/common/portapack_shared_memory.hpp | 3 +++ 3 files changed, 18 insertions(+) diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 33c81ad3..a8705abc 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -145,6 +145,10 @@ void EventDispatcher::dispatch(const eventmask_t events) { handle_application_queue(); } + if( events & EVT_MASK_LOCAL ) { + handle_local_queue(); + } + if( events & EVT_MASK_RTC_TICK ) { handle_rtc_tick(); } @@ -174,6 +178,12 @@ void EventDispatcher::handle_application_queue() { }); } +void EventDispatcher::handle_local_queue() { + shared_memory.app_local_queue.handle([](Message* const message) { + message_map.send(message); + }); +} + void EventDispatcher::handle_rtc_tick() { sd_card::poll_inserted(); @@ -288,6 +298,9 @@ void EventDispatcher::init_message_queues() { new (&shared_memory.application_queue) MessageQueue( shared_memory.application_queue_data, SharedMemory::application_queue_k ); + new (&shared_memory.app_local_queue) MessageQueue( + shared_memory.app_local_queue_data, SharedMemory::app_local_queue_k + ); } MessageHandlerRegistration::MessageHandlerRegistration( diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index cdf73e84..fcf36102 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -86,6 +86,7 @@ private: static constexpr auto EVT_MASK_RTC_TICK = EVENT_MASK(0); static constexpr auto EVT_MASK_LCD_FRAME_SYNC = EVENT_MASK(1); static constexpr auto EVT_MASK_APPLICATION = EVENT_MASK(6); + static constexpr auto EVT_MASK_LOCAL = EVENT_MASK(7); static Thread* thread_event_loop; @@ -102,6 +103,7 @@ private: void dispatch(const eventmask_t events); void handle_application_queue(); + void handle_local_queue(); void handle_rtc_tick(); static ui::Widget* touch_widget(ui::Widget* const w, ui::TouchEvent event); diff --git a/firmware/common/portapack_shared_memory.hpp b/firmware/common/portapack_shared_memory.hpp index 3310f033..a2ffe841 100644 --- a/firmware/common/portapack_shared_memory.hpp +++ b/firmware/common/portapack_shared_memory.hpp @@ -35,11 +35,14 @@ struct TouchADCFrame { struct SharedMemory { static constexpr size_t baseband_queue_k = 11; static constexpr size_t application_queue_k = 11; + static constexpr size_t app_local_queue_k = 11; uint8_t baseband_queue_data[1 << baseband_queue_k]; uint8_t application_queue_data[1 << application_queue_k]; + uint8_t app_local_queue_data[1 << app_local_queue_k]; MessageQueue baseband_queue; MessageQueue application_queue; + MessageQueue app_local_queue; // TODO: M0 should directly configure and control DMA channel that is // acquiring ADC samples. From 76c5fe96af0876290b050add6c3f43b292f55677 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:00:42 -0700 Subject: [PATCH 069/165] Use app-local queue for messages coming from application. Messages are now deferred until application thread call stack unwinds, events are checked. --- firmware/application/event_m0.cpp | 4 ---- firmware/application/event_m0.hpp | 6 +++++- firmware/application/ui_navigation.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index a8705abc..6d387cf0 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -119,10 +119,6 @@ void EventDispatcher::request_stop() { is_running = false; } -void EventDispatcher::send_message(Message* const message) { - message_map.send(message); -} - void EventDispatcher::set_display_sleep(const bool sleep) { // TODO: Distribute display sleep message more broadly, shut down data generation // on baseband side, since all that data is being discarded during sleep. diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index fcf36102..2a6e7c35 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -80,7 +80,11 @@ public: } } - static void send_message(Message* const message); + template + static void send_message(T& message) { + shared_memory.app_local_queue.push(message); + events_flag_isr(EVT_MASK_LOCAL); + } private: static constexpr auto EVT_MASK_RTC_TICK = EVENT_MASK(0); diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 59de5a23..20110b68 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -63,7 +63,7 @@ SystemStatusView::SystemStatusView() { button_sleep.on_select = [this](ImageButton&) { DisplaySleepMessage message; - EventDispatcher::send_message(&message); + EventDispatcher::send_message(message); }; } From cfaa44b02aee92c408e8f12c28c62b55d21c8156 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:04:10 -0700 Subject: [PATCH 070/165] Send CaptureThread error into app-local message queue. --- firmware/application/capture_thread.cpp | 10 ++++------ firmware/application/capture_thread.hpp | 12 +++++++----- firmware/application/ui_record_view.cpp | 12 ++++++------ firmware/application/ui_record_view.hpp | 12 ++++++++++++ firmware/common/message.hpp | 13 +++++++++++++ 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index 8fab7940..e905deb9 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -77,9 +77,11 @@ Thread* CaptureThread::thread = nullptr; CaptureThread::CaptureThread( std::unique_ptr writer, size_t write_size, - size_t buffer_count + size_t buffer_count, + std::function&& error_callback ) : config { write_size, buffer_count }, - writer { std::move(writer) } + writer { std::move(writer) }, + error_callback { std::move(error_callback) } { // Need significant stack for FATFS thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, CaptureThread::static_fn, this); @@ -94,10 +96,6 @@ CaptureThread::~CaptureThread() { } } -const Optional& CaptureThread::error() const { - return last_error; -} - void CaptureThread::check_fifo_isr() { // TODO: Prevent over-signalling by transmitting a set of // flags from the baseband core. diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index 2b35423e..ce4c1485 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -44,7 +44,8 @@ public: CaptureThread( std::unique_ptr writer, size_t write_size, - size_t buffer_count + size_t buffer_count, + std::function&& error_callback ); ~CaptureThread(); @@ -52,8 +53,6 @@ public: return config; } - const Optional& error() const; - static void check_fifo_isr(); private: @@ -61,12 +60,15 @@ private: CaptureConfig config; std::unique_ptr writer; - Optional last_error; + std::function error_callback; static Thread* thread; static msg_t static_fn(void* arg) { auto obj = static_cast(arg); - obj->last_error = obj->run(); + const auto error = obj->run(); + if( error.is_valid() && obj->error_callback ) { + obj->error_callback(error.value()); + } return 0; } diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 4d385e15..a11aefd3 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -269,7 +269,11 @@ void RecordView::start() { button_record.set_bitmap(&bitmap_stop); capture_thread = std::make_unique( std::move(writer), - write_size, buffer_count + write_size, buffer_count, + [](File::Error error) { + CaptureThreadErrorMessage message { error.code() }; + EventDispatcher::send_message(message); + } ); } } @@ -301,11 +305,6 @@ Optional RecordView::write_metadata_file(const std::string& filenam void RecordView::on_tick_second() { if( is_active() ) { - const auto error = capture_thread->error(); - if( error.is_valid() ) { - stop(); - report_error(error.value().what()); - } const auto dropped_percent = std::min(99U, capture_thread->state().dropped_percent()); const auto s = to_string_dec_uint(dropped_percent, 2, ' ') + "\%"; text_record_dropped.set(s); @@ -328,6 +327,7 @@ void RecordView::on_tick_second() { } void RecordView::report_error(const std::string& message) { + stop(); if( on_error ) { on_error(message); } diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index ddc72e9f..d6111bf1 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -115,6 +115,18 @@ private: }; std::unique_ptr capture_thread; + + MessageHandlerRegistration message_handler_capture_thread_error { + Message::ID::CaptureThreadError, + [this](const Message* const p) { + const auto message = *reinterpret_cast(p); + this->on_capture_thread_error(message.error); + } + }; + + void on_capture_thread_error(File::Error error) { + report_error(error.what()); + } }; } /* namespace ui */ diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 640cd1d0..8ee6cfe7 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -64,6 +64,7 @@ public: SpectrumStreamingConfig = 15, DisplaySleep = 16, CaptureConfig = 17, + CaptureThreadError = 18, MAX }; @@ -494,4 +495,16 @@ public: CaptureConfig* const config; }; +class CaptureThreadErrorMessage : public Message { +public: + constexpr CaptureThreadErrorMessage( + uint32_t error + ) : Message { ID::CaptureThreadError }, + error { error } + { + } + + uint32_t error; +}; + #endif/*__MESSAGE_H__*/ From 320d979924e121595237d1878c607a2710e637ab Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:13:58 -0700 Subject: [PATCH 071/165] Simplify CaptureThread error callback functions. --- firmware/application/ui_record_view.cpp | 10 +++++----- firmware/application/ui_record_view.hpp | 8 ++------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index a11aefd3..829d8b0f 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -233,7 +233,7 @@ void RecordView::start() { filename_stem + ".WAV" ); if( create_error.is_valid() ) { - report_error(create_error.value().what()); + handle_error(create_error.value()); } else { writer = std::move(p); } @@ -244,7 +244,7 @@ void RecordView::start() { { const auto metadata_file_error = write_metadata_file(filename_stem + ".TXT"); if( metadata_file_error.is_valid() ) { - report_error(metadata_file_error.value().what()); + handle_error(metadata_file_error.value()); return; } @@ -253,7 +253,7 @@ void RecordView::start() { filename_stem + ".C16" ); if( create_error.is_valid() ) { - report_error(create_error.value().what()); + handle_error(create_error.value()); } else { writer = std::move(p); } @@ -326,10 +326,10 @@ void RecordView::on_tick_second() { } } -void RecordView::report_error(const std::string& message) { +void RecordView::handle_error(const File::Error error) { stop(); if( on_error ) { - on_error(message); + on_error(error.what()); } } diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index d6111bf1..14f49877 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -79,7 +79,7 @@ private: void on_tick_second(); - void report_error(const std::string& message); + void handle_error(const File::Error error); const std::string filename_stem_pattern; const FileType file_type; @@ -120,13 +120,9 @@ private: Message::ID::CaptureThreadError, [this](const Message* const p) { const auto message = *reinterpret_cast(p); - this->on_capture_thread_error(message.error); + this->handle_error(message.error); } }; - - void on_capture_thread_error(File::Error error) { - report_error(error.what()); - } }; } /* namespace ui */ From 59aa99c8ff469d93ea62db532d39a77d6553b850 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:19:22 -0700 Subject: [PATCH 072/165] Whoops, use events_flag(), not events_flag_isr(). --- firmware/application/event_m0.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 2a6e7c35..35de0e4d 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -83,7 +83,7 @@ public: template static void send_message(T& message) { shared_memory.app_local_queue.push(message); - events_flag_isr(EVT_MASK_LOCAL); + events_flag(EVT_MASK_LOCAL); } private: From 19e5e111a9a5dec189982df7f89037ef9c56d347 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:33:23 -0700 Subject: [PATCH 073/165] Move UIRecordView::set_sampling_rate to .cpp. --- firmware/application/ui_record_view.cpp | 13 +++++++++++++ firmware/application/ui_record_view.hpp | 13 +------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 829d8b0f..02f64a01 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -195,6 +195,19 @@ void RecordView::focus() { button_record.focus(); } +void RecordView::set_sampling_rate(const size_t new_sampling_rate) { + if( new_sampling_rate != sampling_rate ) { + stop(); + sampling_rate = new_sampling_rate; + + button_record.hidden(sampling_rate == 0); + text_record_filename.hidden(sampling_rate == 0); + text_record_dropped.hidden(sampling_rate == 0); + text_time_available.hidden(sampling_rate == 0); + rect_background.hidden(sampling_rate != 0); + } +} + bool RecordView::is_active() const { return (bool)capture_thread; } diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 14f49877..85d6e26c 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -55,18 +55,7 @@ public: void focus() override; - void set_sampling_rate(const size_t new_sampling_rate) { - if( new_sampling_rate != sampling_rate ) { - stop(); - sampling_rate = new_sampling_rate; - - button_record.hidden(sampling_rate == 0); - text_record_filename.hidden(sampling_rate == 0); - text_record_dropped.hidden(sampling_rate == 0); - text_time_available.hidden(sampling_rate == 0); - rect_background.hidden(sampling_rate != 0); - } - } + void set_sampling_rate(const size_t new_sampling_rate); void start(); void stop(); From 44fb66b4f96c3044d8bbd5ed9969ee7476d2673b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:35:15 -0700 Subject: [PATCH 074/165] Rename UIRecordView::on_tick_second() -> update_status_display(). --- firmware/application/ui_record_view.cpp | 4 ++++ firmware/application/ui_record_view.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 02f64a01..cdc9d7aa 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -317,6 +317,10 @@ Optional RecordView::write_metadata_file(const std::string& filenam } void RecordView::on_tick_second() { + update_status_display(); +} + +void RecordView::update_status_display() { if( is_active() ) { const auto dropped_percent = std::min(99U, capture_thread->state().dropped_percent()); const auto s = to_string_dec_uint(dropped_percent, 2, ' ') + "\%"; diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 85d6e26c..c0d8bc5d 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -67,6 +67,7 @@ private: Optional write_metadata_file(const std::string& filename); void on_tick_second(); + void update_status_display(); void handle_error(const File::Error error); From 0e33d7e5d036998bfa4da3530d2353b390a53f8d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:35:41 -0700 Subject: [PATCH 075/165] Refresh UIRecordVide status display when appropriate. --- firmware/application/ui_record_view.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index cdc9d7aa..6fb74e66 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -205,6 +205,8 @@ void RecordView::set_sampling_rate(const size_t new_sampling_rate) { text_record_dropped.hidden(sampling_rate == 0); text_time_available.hidden(sampling_rate == 0); rect_background.hidden(sampling_rate != 0); + + update_status_display(); } } @@ -289,6 +291,8 @@ void RecordView::start() { } ); } + + update_status_display(); } void RecordView::stop() { @@ -296,6 +300,8 @@ void RecordView::stop() { capture_thread.reset(); button_record.set_bitmap(&bitmap_record); } + + update_status_display(); } Optional RecordView::write_metadata_file(const std::string& filename) { From 4ffb05212e21897d3a163ca21b142730d0bda1ca Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:52:05 -0700 Subject: [PATCH 076/165] Pass error_callback by value. --- firmware/application/capture_thread.cpp | 2 +- firmware/application/capture_thread.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index e905deb9..f4935e7c 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -78,7 +78,7 @@ CaptureThread::CaptureThread( std::unique_ptr writer, size_t write_size, size_t buffer_count, - std::function&& error_callback + std::function error_callback ) : config { write_size, buffer_count }, writer { std::move(writer) }, error_callback { std::move(error_callback) } diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index ce4c1485..8facb521 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -45,7 +45,7 @@ public: std::unique_ptr writer, size_t write_size, size_t buffer_count, - std::function&& error_callback + std::function error_callback ); ~CaptureThread(); From 81d4e59aeb234df60ef09c63d30f2551ff4b3f9a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 11:53:07 -0700 Subject: [PATCH 077/165] Add CaptureThread success_callback. --- firmware/application/capture_thread.cpp | 2 ++ firmware/application/capture_thread.hpp | 6 ++++++ firmware/application/ui_record_view.cpp | 4 ++++ firmware/common/message.hpp | 2 +- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index f4935e7c..47ea252e 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -78,9 +78,11 @@ CaptureThread::CaptureThread( std::unique_ptr writer, size_t write_size, size_t buffer_count, + std::function success_callback, std::function error_callback ) : config { write_size, buffer_count }, writer { std::move(writer) }, + success_callback { std::move(success_callback) }, error_callback { std::move(error_callback) } { // Need significant stack for FATFS diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index 8facb521..7fddd1f5 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -45,6 +45,7 @@ public: std::unique_ptr writer, size_t write_size, size_t buffer_count, + std::function success_callback, std::function error_callback ); ~CaptureThread(); @@ -60,6 +61,7 @@ private: CaptureConfig config; std::unique_ptr writer; + std::function success_callback; std::function error_callback; static Thread* thread; @@ -68,6 +70,10 @@ private: const auto error = obj->run(); if( error.is_valid() && obj->error_callback ) { obj->error_callback(error.value()); + } else { + if( obj->success_callback ) { + obj->success_callback(); + } } return 0; } diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 6fb74e66..c049ec84 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -285,6 +285,10 @@ void RecordView::start() { capture_thread = std::make_unique( std::move(writer), write_size, buffer_count, + []() { + CaptureThreadErrorMessage message { }; + EventDispatcher::send_message(message); + }, [](File::Error error) { CaptureThreadErrorMessage message { error.code() }; EventDispatcher::send_message(message); diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 8ee6cfe7..c4864adc 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -498,7 +498,7 @@ public: class CaptureThreadErrorMessage : public Message { public: constexpr CaptureThreadErrorMessage( - uint32_t error + uint32_t error = 0 ) : Message { ID::CaptureThreadError }, error { error } { From 264c19b312ce5237b4f91d7bea72db21b4bfb705 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 12:05:55 -0700 Subject: [PATCH 078/165] Rename CaptureThread message, callback method, handle success. --- firmware/application/ui_record_view.cpp | 12 +++++++++--- firmware/application/ui_record_view.hpp | 7 ++++--- firmware/common/message.hpp | 8 ++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index c049ec84..09627510 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -286,11 +286,11 @@ void RecordView::start() { std::move(writer), write_size, buffer_count, []() { - CaptureThreadErrorMessage message { }; + CaptureThreadDoneMessage message { }; EventDispatcher::send_message(message); }, [](File::Error error) { - CaptureThreadErrorMessage message { error.code() }; + CaptureThreadDoneMessage message { error.code() }; EventDispatcher::send_message(message); } ); @@ -353,8 +353,14 @@ void RecordView::update_status_display() { } } -void RecordView::handle_error(const File::Error error) { +void RecordView::handle_capture_thread_done(const File::Error error) { stop(); + if( error.code() ) { + handle_error(error); + } +} + +void RecordView::handle_error(const File::Error error) { if( on_error ) { on_error(error.what()); } diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index c0d8bc5d..023fb0d5 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -69,6 +69,7 @@ private: void on_tick_second(); void update_status_display(); + void handle_capture_thread_done(const File::Error error); void handle_error(const File::Error error); const std::string filename_stem_pattern; @@ -107,10 +108,10 @@ private: std::unique_ptr capture_thread; MessageHandlerRegistration message_handler_capture_thread_error { - Message::ID::CaptureThreadError, + Message::ID::CaptureThreadDone, [this](const Message* const p) { - const auto message = *reinterpret_cast(p); - this->handle_error(message.error); + const auto message = *reinterpret_cast(p); + this->handle_capture_thread_done(message.error); } }; }; diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index c4864adc..725c328b 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -64,7 +64,7 @@ public: SpectrumStreamingConfig = 15, DisplaySleep = 16, CaptureConfig = 17, - CaptureThreadError = 18, + CaptureThreadDone = 18, MAX }; @@ -495,11 +495,11 @@ public: CaptureConfig* const config; }; -class CaptureThreadErrorMessage : public Message { +class CaptureThreadDoneMessage : public Message { public: - constexpr CaptureThreadErrorMessage( + constexpr CaptureThreadDoneMessage( uint32_t error = 0 - ) : Message { ID::CaptureThreadError }, + ) : Message { ID::CaptureThreadDone }, error { error } { } From 003ce4990d135a4e1c8027c06f2ee78978ca8a73 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 12:15:57 -0700 Subject: [PATCH 079/165] Move CaptureThread::static_fn into .cpp. --- firmware/application/capture_thread.cpp | 13 +++++++++++++ firmware/application/capture_thread.hpp | 13 +------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index 47ea252e..4de5cd53 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -109,6 +109,19 @@ void CaptureThread::check_fifo_isr() { } } +msg_t CaptureThread::static_fn(void* arg) { + auto obj = static_cast(arg); + const auto error = obj->run(); + if( error.is_valid() && obj->error_callback ) { + obj->error_callback(error.value()); + } else { + if( obj->success_callback ) { + obj->success_callback(); + } + } + return 0; +} + Optional CaptureThread::run() { StreamOutput stream { &config }; diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index 7fddd1f5..849a3131 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -65,18 +65,7 @@ private: std::function error_callback; static Thread* thread; - static msg_t static_fn(void* arg) { - auto obj = static_cast(arg); - const auto error = obj->run(); - if( error.is_valid() && obj->error_callback ) { - obj->error_callback(error.value()); - } else { - if( obj->success_callback ) { - obj->success_callback(); - } - } - return 0; - } + static msg_t static_fn(void* arg); Optional run(); }; From b34512e3d68efa365b060161fa0a8012faabeab0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 21 Jun 2016 15:23:51 -0700 Subject: [PATCH 080/165] Eliminate a buffer_t copy/duplication. --- firmware/baseband/proc_tpms.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index 3052e4a5..7c6c83d6 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -32,8 +32,7 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { /* 2.4576MHz, 2048 samples */ const auto decim_0_out = decim_0.execute(buffer, dst_buffer); - const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer); - const auto decimator_out = decim_1_out; + const auto decimator_out = decim_1.execute(decim_0_out, dst_buffer); /* 307.2kHz, 256 samples */ feed_channel_stats(decimator_out); @@ -44,8 +43,8 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { } } - for(size_t i=0; i Date: Tue, 21 Jun 2016 15:36:57 -0700 Subject: [PATCH 081/165] TPMS: Allow band selection: 315 or 433.92 (~434) MHz. --- firmware/application/tpms_app.cpp | 17 ++++++++++++++++- firmware/application/tpms_app.hpp | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index aa03ba68..878ba1f2 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -167,6 +167,7 @@ TPMSAppView::TPMSAppView(NavigationView&) { add_children({ { &rssi, &channel, + &options_band, &field_rf_amp, &field_lna, &field_vga, @@ -190,6 +191,11 @@ TPMSAppView::TPMSAppView(NavigationView&) { .decimation_factor = 1, }); + options_band.on_change = [this](size_t, OptionsField::value_t v) { + this->on_band_changed(v); + }; + options_band.set_by_value(target_frequency()); + logger = std::make_unique(); if( logger ) { logger->append("tpms.txt"); @@ -228,8 +234,17 @@ void TPMSAppView::on_show_list() { recent_entries_view.focus(); } +void TPMSAppView::on_band_changed(const uint32_t new_band_frequency) { + set_target_frequency(new_band_frequency); +} + +void TPMSAppView::set_target_frequency(const uint32_t new_value) { + target_frequency_ = new_value; + radio::set_tuning_frequency(tuning_frequency()); +} + uint32_t TPMSAppView::target_frequency() const { - return initial_target_frequency; + return target_frequency_; } uint32_t TPMSAppView::tuning_frequency() const { diff --git a/firmware/application/tpms_app.hpp b/firmware/application/tpms_app.hpp index 707208c7..84aacd61 100644 --- a/firmware/application/tpms_app.hpp +++ b/firmware/application/tpms_app.hpp @@ -129,6 +129,15 @@ private: { 21 * 8, 5, 6 * 8, 4 }, }; + OptionsField options_band { + { 0 * 8, 0 * 16 }, + 3, + { + { "315", 315000000 }, + { "434", 433920000 }, + } + }; + RFAmpField field_rf_amp { { 13 * 8, 0 * 16 } }; @@ -146,10 +155,16 @@ private: TPMSRecentEntriesView recent_entries_view { recent }; + uint32_t target_frequency_ = initial_target_frequency; + void on_packet(const tpms::Packet& packet); void on_show_list(); + void on_band_changed(const uint32_t new_band_frequency); + uint32_t target_frequency() const; + void set_target_frequency(const uint32_t new_value); + uint32_t tuning_frequency() const; }; From 1010e6a234e06e72ecc995ac06082309ce69322d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 22 Jun 2016 11:22:28 -0700 Subject: [PATCH 082/165] Remove unused DMA Handler types. --- firmware/baseband/baseband_dma.hpp | 2 -- firmware/baseband/rssi_dma.hpp | 2 -- firmware/baseband/touch_dma.hpp | 2 -- 3 files changed, 6 deletions(-) diff --git a/firmware/baseband/baseband_dma.hpp b/firmware/baseband/baseband_dma.hpp index cc41a751..94827d4b 100644 --- a/firmware/baseband/baseband_dma.hpp +++ b/firmware/baseband/baseband_dma.hpp @@ -31,8 +31,6 @@ namespace baseband { namespace dma { -using Handler = void (*)(); - void init(); void configure( baseband::sample_t* const buffer_base, diff --git a/firmware/baseband/rssi_dma.hpp b/firmware/baseband/rssi_dma.hpp index e543dcf6..263dcfcf 100644 --- a/firmware/baseband/rssi_dma.hpp +++ b/firmware/baseband/rssi_dma.hpp @@ -30,8 +30,6 @@ namespace rf { namespace rssi { namespace dma { -using Handler = void (*)(); - void init(); void allocate(size_t buffer_count, size_t items_per_buffer); diff --git a/firmware/baseband/touch_dma.hpp b/firmware/baseband/touch_dma.hpp index 777230e4..13c92b21 100644 --- a/firmware/baseband/touch_dma.hpp +++ b/firmware/baseband/touch_dma.hpp @@ -32,8 +32,6 @@ namespace dma { using sample_t = uint32_t; using buffer_t = buffer_t; -using Handler = void (*)(); - void init(); void allocate(); From fead46cc46798168a79c9a60deec70051b928f6a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 23 Jun 2016 12:03:47 -0700 Subject: [PATCH 083/165] Fix state management in Capture mode. Don't alter ReceiverModel modulation/mode when capturing. --- firmware/application/capture_app.cpp | 48 ++++++++++++++++++++++------ firmware/application/capture_app.hpp | 7 +++- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 218b0583..772cb2a8 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -21,9 +21,14 @@ #include "capture_app.hpp" +#include "baseband_api.hpp" + #include "portapack.hpp" using namespace portapack; +#include "portapack_persistent_memory.hpp" +using namespace portapack; + namespace ui { CaptureAppView::CaptureAppView(NavigationView& nav) { @@ -38,27 +43,36 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { &waterfall, } }); - field_frequency.set_value(receiver_model.tuning_frequency()); + field_frequency.set_value(target_frequency()); field_frequency.set_step(receiver_model.frequency_step()); field_frequency.on_change = [this](rf::Frequency f) { - this->on_tuning_frequency_changed(f); + this->on_target_frequency_changed(f); }; field_frequency.on_edit = [this, &nav]() { // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(receiver_model.tuning_frequency()); + auto new_view = nav.push(this->target_frequency()); new_view->on_changed = [this](rf::Frequency f) { - this->on_tuning_frequency_changed(f); + this->on_target_frequency_changed(f); this->field_frequency.set_value(f); }; }; - receiver_model.set_baseband_configuration({ + radio::enable({ + tuning_frequency(), + sampling_rate, + baseband_bandwidth, + rf::Direction::Receive, + receiver_model.rf_amp(), + static_cast(receiver_model.lna()), + static_cast(receiver_model.vga()), + 1, + }); + + baseband::start({ .mode = toUType(ReceiverModel::Mode::Capture), .sampling_rate = sampling_rate, .decimation_factor = 1, }); - receiver_model.set_baseband_bandwidth(baseband_bandwidth); - receiver_model.enable(); record_view.set_sampling_rate(sampling_rate / 8); record_view.on_error = [&nav](std::string message) { @@ -67,7 +81,8 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { } CaptureAppView::~CaptureAppView() { - receiver_model.disable(); + baseband::stop(); + radio::disable(); } void CaptureAppView::on_hide() { @@ -88,8 +103,21 @@ void CaptureAppView::focus() { record_view.focus(); } -void CaptureAppView::on_tuning_frequency_changed(rf::Frequency f) { - receiver_model.set_tuning_frequency(f); +void CaptureAppView::on_target_frequency_changed(rf::Frequency f) { + set_target_frequency(f); +} + +void CaptureAppView::set_target_frequency(const rf::Frequency new_value) { + persistent_memory::set_tuned_frequency(new_value);; + radio::set_tuning_frequency(tuning_frequency()); +} + +rf::Frequency CaptureAppView::target_frequency() const { + return persistent_memory::tuned_frequency(); +} + +rf::Frequency CaptureAppView::tuning_frequency() const { + return target_frequency() - (sampling_rate / 4); } } /* namespace ui */ diff --git a/firmware/application/capture_app.hpp b/firmware/application/capture_app.hpp index 985bdb8d..e6a4b90e 100644 --- a/firmware/application/capture_app.hpp +++ b/firmware/application/capture_app.hpp @@ -52,7 +52,12 @@ private: static constexpr uint32_t sampling_rate = 4000000; static constexpr uint32_t baseband_bandwidth = 2500000; - void on_tuning_frequency_changed(rf::Frequency f); + void on_target_frequency_changed(rf::Frequency f); + + rf::Frequency target_frequency() const; + void set_target_frequency(const rf::Frequency new_value); + + rf::Frequency tuning_frequency() const; RSSI rssi { { 21 * 8, 0, 6 * 8, 4 }, From ac0bdc35a618f6d389ffefc6ea53c2aef4ce296b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 23 Jun 2016 22:11:47 -0700 Subject: [PATCH 084/165] Set TPMS app initial focus. --- firmware/application/tpms_app.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index 878ba1f2..19d84f4a 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -208,7 +208,7 @@ TPMSAppView::~TPMSAppView() { } void TPMSAppView::focus() { - recent_entries_view.focus(); + options_band.focus(); } void TPMSAppView::set_parent_rect(const Rect new_parent_rect) { From 303bfeaafc91936e15a4fdba1bf013df7d5c4c6e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 11:30:54 -0700 Subject: [PATCH 085/165] Run baseband image per application. First step toward having separate baseband images per app or function. --- firmware/application/ais_app.cpp | 4 ++++ firmware/application/analog_audio_app.cpp | 6 ++++++ firmware/application/baseband_api.cpp | 6 ++++++ firmware/application/baseband_api.hpp | 3 +++ firmware/application/capture_app.cpp | 4 ++++ firmware/application/ert_app.cpp | 4 ++++ firmware/application/main.cpp | 9 --------- firmware/application/tpms_app.cpp | 4 ++++ 8 files changed, 31 insertions(+), 9 deletions(-) diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index f8e94878..47da4bbd 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -286,6 +286,8 @@ void AISRecentEntryDetailView::set_entry(const AISRecentEntry& entry) { } AISAppView::AISAppView(NavigationView&) { + baseband::run_image(portapack::spi_flash::baseband); + add_children({ { &label_channel, &options_channel, @@ -333,6 +335,8 @@ AISAppView::AISAppView(NavigationView&) { AISAppView::~AISAppView() { baseband::stop(); radio::disable(); + + baseband::shutdown(); } void AISAppView::focus() { diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 4145d2c4..a7304aca 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -21,6 +21,8 @@ #include "analog_audio_app.hpp" +#include "baseband_api.hpp" + #include "portapack.hpp" #include "portapack_persistent_memory.hpp" using namespace portapack; @@ -77,6 +79,8 @@ NBFMOptionsView::NBFMOptionsView( AnalogAudioView::AnalogAudioView( NavigationView& nav ) { + baseband::run_image(portapack::spi_flash::baseband); + add_children({ { &rssi, &channel, @@ -145,6 +149,8 @@ AnalogAudioView::~AnalogAudioView() { audio::output::stop(); receiver_model.disable(); + + baseband::shutdown(); } void AnalogAudioView::on_hide() { diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index e3acad31..391b8f1f 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -26,6 +26,8 @@ #include "portapack_shared_memory.hpp" +#include "core_control.hpp" + namespace baseband { void AMConfig::apply() const { @@ -81,6 +83,10 @@ void stop() { ); } +void run_image(const portapack::spi_flash::region_t image_region) { + m4_init(image_region, portapack::memory::map::m4_code); +} + void shutdown() { ShutdownMessage shutdown_message; shared_memory.baseband_queue.push(shutdown_message); diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index b029e2ec..f909b1a6 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -26,6 +26,8 @@ #include "dsp_fir_taps.hpp" +#include "spi_image.hpp" + #include namespace baseband { @@ -53,6 +55,7 @@ struct WFMConfig { void start(BasebandConfiguration configuration); void stop(); +void run_image(const portapack::spi_flash::region_t image_region); void shutdown(); void spectrum_streaming_start(); diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 772cb2a8..58af2526 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -32,6 +32,8 @@ using namespace portapack; namespace ui { CaptureAppView::CaptureAppView(NavigationView& nav) { + baseband::run_image(portapack::spi_flash::baseband); + add_children({ { &rssi, &channel, @@ -83,6 +85,8 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { CaptureAppView::~CaptureAppView() { baseband::stop(); radio::disable(); + + baseband::shutdown(); } void CaptureAppView::on_hide() { diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 61501b47..467dbbc2 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -121,6 +121,8 @@ void RecentEntriesView::draw( } ERTAppView::ERTAppView(NavigationView&) { + baseband::run_image(portapack::spi_flash::baseband); + add_children({ { &recent_entries_view, } }); @@ -149,6 +151,8 @@ ERTAppView::ERTAppView(NavigationView&) { ERTAppView::~ERTAppView() { baseband::stop(); radio::disable(); + + baseband::shutdown(); } void ERTAppView::focus() { diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 0475073c..5e52ee7e 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -59,13 +59,6 @@ static void event_loop() { }; EventDispatcher event_dispatcher { &system_view, context }; - - MessageHandlerRegistration message_handler_shutdown { - Message::ID::Shutdown, - [&event_dispatcher](const Message* const) { - event_dispatcher.request_stop(); - } - }; MessageHandlerRegistration message_handler_display_sleep { Message::ID::DisplaySleep, [&event_dispatcher](const Message* const) { @@ -88,8 +81,6 @@ int main(void) { sdcStart(&SDCD1, nullptr); - m4_init(portapack::spi_flash::baseband, portapack::memory::map::m4_code); - controls_init(); lcd_frame_sync_configure(); rtc_interrupt_enable(); diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index 19d84f4a..f46b1549 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -164,6 +164,8 @@ void RecentEntriesView::draw( } TPMSAppView::TPMSAppView(NavigationView&) { + baseband::run_image(portapack::spi_flash::baseband); + add_children({ { &rssi, &channel, @@ -205,6 +207,8 @@ TPMSAppView::TPMSAppView(NavigationView&) { TPMSAppView::~TPMSAppView() { baseband::stop(); radio::disable(); + + baseband::shutdown(); } void TPMSAppView::focus() { From c7497577a0652ab1dfea03866970407329eef02b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 11:31:41 -0700 Subject: [PATCH 086/165] Make all app->baseband messages synchronous. No idea why they shouldn't be... --- firmware/application/baseband_api.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 391b8f1f..a1eb30cb 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -39,7 +39,7 @@ void AMConfig::apply() const { modulation, audio_12k_hpf_300hz_config }; - shared_memory.baseband_queue.push(message); + shared_memory.baseband_queue.push_and_wait(message); audio::set_rate(audio::Rate::Hz_12000); } @@ -53,7 +53,7 @@ void NBFMConfig::apply() const { audio_24k_hpf_300hz_config, audio_24k_deemph_300_6_config }; - shared_memory.baseband_queue.push(message); + shared_memory.baseband_queue.push_and_wait(message); audio::set_rate(audio::Rate::Hz_24000); } @@ -66,13 +66,13 @@ void WFMConfig::apply() const { audio_48k_hpf_30hz_config, audio_48k_deemph_2122_6_config }; - shared_memory.baseband_queue.push(message); + shared_memory.baseband_queue.push_and_wait(message); audio::set_rate(audio::Rate::Hz_48000); } void start(BasebandConfiguration configuration) { BasebandConfigurationMessage message { configuration }; - shared_memory.baseband_queue.push(message); + shared_memory.baseband_queue.push_and_wait(message); } void stop() { @@ -89,7 +89,7 @@ void run_image(const portapack::spi_flash::region_t image_region) { void shutdown() { ShutdownMessage shutdown_message; - shared_memory.baseband_queue.push(shutdown_message); + shared_memory.baseband_queue.push_and_wait(shutdown_message); } void spectrum_streaming_start() { From e263420ea33d7ad9b8182642ed565ad6cea13010 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 11:32:24 -0700 Subject: [PATCH 087/165] Enable M4 interrupt on M0 core only when M4 image is running. --- firmware/application/baseband_api.cpp | 4 ++++ firmware/application/event_m0.cpp | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index a1eb30cb..71c41fe9 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -85,9 +85,13 @@ void stop() { void run_image(const portapack::spi_flash::region_t image_region) { m4_init(image_region, portapack::memory::map::m4_code); + + creg::m4txevent::enable(); } void shutdown() { + creg::m4txevent::disable(); + ShutdownMessage shutdown_message; shared_memory.baseband_queue.push_and_wait(shutdown_message); } diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 6d387cf0..7966152a 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -105,14 +105,10 @@ EventDispatcher::EventDispatcher( } void EventDispatcher::run() { - creg::m4txevent::enable(); - while(is_running) { const auto events = wait(); dispatch(events); } - - creg::m4txevent::disable(); } void EventDispatcher::request_stop() { From 61325e46969e0c48a4acd63ce0b42fa3d95f4a9e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 13:44:40 -0700 Subject: [PATCH 088/165] Enable M4 interrupt from M0 only when expected. --- firmware/baseband/event_m4.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/firmware/baseband/event_m4.cpp b/firmware/baseband/event_m4.cpp index 797ef5cb..8140cd26 100644 --- a/firmware/baseband/event_m4.cpp +++ b/firmware/baseband/event_m4.cpp @@ -53,12 +53,13 @@ Thread* EventDispatcher::thread_event_loop = nullptr; void EventDispatcher::run() { thread_event_loop = chThdSelf(); - lpc43xx::creg::m0apptxevent::enable(); baseband_thread.thread_main = chThdSelf(); baseband_thread.thread_rssi = rssi_thread.start(NORMALPRIO + 10); baseband_thread.start(NORMALPRIO + 20); + lpc43xx::creg::m0apptxevent::enable(); + while(is_running) { const auto events = wait(); dispatch(events); From d41c6ee36a1ffa144f950167c5b9676ed08a9c1e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 14:16:45 -0700 Subject: [PATCH 089/165] Simplify app->baseband message handling. No need for a FIFO when all messages are intended to be synchronous. --- firmware/application/baseband_api.cpp | 57 +++++++++++---------- firmware/application/event_m0.cpp | 4 +- firmware/baseband/event_m4.cpp | 8 +-- firmware/common/portapack_shared_memory.hpp | 4 +- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 71c41fe9..93dd0180 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -30,6 +30,14 @@ namespace baseband { +static void send_message(const Message* const message) { + // If message is only sent by this function via one thread, no need to check if + // another message is present before setting new message. + shared_memory.baseband_message = message; + creg::m0apptxevent::assert(); + while(shared_memory.baseband_message); +} + void AMConfig::apply() const { const AMConfigureMessage message { taps_6k0_decim_0, @@ -39,7 +47,7 @@ void AMConfig::apply() const { modulation, audio_12k_hpf_300hz_config }; - shared_memory.baseband_queue.push_and_wait(message); + send_message(&message); audio::set_rate(audio::Rate::Hz_12000); } @@ -53,7 +61,7 @@ void NBFMConfig::apply() const { audio_24k_hpf_300hz_config, audio_24k_deemph_300_6_config }; - shared_memory.baseband_queue.push_and_wait(message); + send_message(&message); audio::set_rate(audio::Rate::Hz_24000); } @@ -66,21 +74,20 @@ void WFMConfig::apply() const { audio_48k_hpf_30hz_config, audio_48k_deemph_2122_6_config }; - shared_memory.baseband_queue.push_and_wait(message); + send_message(&message); audio::set_rate(audio::Rate::Hz_48000); } void start(BasebandConfiguration configuration) { BasebandConfigurationMessage message { configuration }; - shared_memory.baseband_queue.push_and_wait(message); + send_message(&message); } void stop() { - shared_memory.baseband_queue.push_and_wait( - BasebandConfigurationMessage { - .configuration = { }, - } - ); + BasebandConfigurationMessage message { + .configuration = { }, + }; + send_message(&message); } void run_image(const portapack::spi_flash::region_t image_region) { @@ -92,36 +99,32 @@ void run_image(const portapack::spi_flash::region_t image_region) { void shutdown() { creg::m4txevent::disable(); - ShutdownMessage shutdown_message; - shared_memory.baseband_queue.push_and_wait(shutdown_message); + ShutdownMessage message; + send_message(&message); } void spectrum_streaming_start() { - shared_memory.baseband_queue.push_and_wait( - SpectrumStreamingConfigMessage { - SpectrumStreamingConfigMessage::Mode::Running - } - ); + SpectrumStreamingConfigMessage message { + SpectrumStreamingConfigMessage::Mode::Running + }; + send_message(&message); } void spectrum_streaming_stop() { - shared_memory.baseband_queue.push_and_wait( - SpectrumStreamingConfigMessage { - SpectrumStreamingConfigMessage::Mode::Stopped - } - ); + SpectrumStreamingConfigMessage message { + SpectrumStreamingConfigMessage::Mode::Stopped + }; + send_message(&message); } void capture_start(CaptureConfig* const config) { - shared_memory.baseband_queue.push_and_wait( - CaptureConfigMessage { config } - ); + CaptureConfigMessage message { config }; + send_message(&message); } void capture_stop() { - shared_memory.baseband_queue.push_and_wait( - CaptureConfigMessage { nullptr } - ); + CaptureConfigMessage message { nullptr }; + send_message(&message); } } /* namespace baseband */ diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 7966152a..96df09a4 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -284,9 +284,7 @@ void EventDispatcher::event_bubble_encoder(const ui::EncoderEvent event) { } void EventDispatcher::init_message_queues() { - new (&shared_memory.baseband_queue) MessageQueue( - shared_memory.baseband_queue_data, SharedMemory::baseband_queue_k - ); + shared_memory.baseband_message = nullptr; new (&shared_memory.application_queue) MessageQueue( shared_memory.application_queue_data, SharedMemory::application_queue_k ); diff --git a/firmware/baseband/event_m4.cpp b/firmware/baseband/event_m4.cpp index 8140cd26..d956f2c0 100644 --- a/firmware/baseband/event_m4.cpp +++ b/firmware/baseband/event_m4.cpp @@ -87,9 +87,11 @@ void EventDispatcher::dispatch(const eventmask_t events) { } void EventDispatcher::handle_baseband_queue() { - shared_memory.baseband_queue.handle([this](Message* const message) { - this->on_message(message); - }); + const auto message = shared_memory.baseband_message; + if( message ) { + on_message(message); + shared_memory.baseband_message = nullptr; + } } void EventDispatcher::on_message(const Message* const message) { diff --git a/firmware/common/portapack_shared_memory.hpp b/firmware/common/portapack_shared_memory.hpp index a2ffe841..ce58f9fa 100644 --- a/firmware/common/portapack_shared_memory.hpp +++ b/firmware/common/portapack_shared_memory.hpp @@ -33,14 +33,12 @@ struct TouchADCFrame { /* NOTE: These structures must be located in the same location in both M4 and M0 binaries */ struct SharedMemory { - static constexpr size_t baseband_queue_k = 11; static constexpr size_t application_queue_k = 11; static constexpr size_t app_local_queue_k = 11; - uint8_t baseband_queue_data[1 << baseband_queue_k]; uint8_t application_queue_data[1 << application_queue_k]; uint8_t app_local_queue_data[1 << app_local_queue_k]; - MessageQueue baseband_queue; + const Message* volatile baseband_message; MessageQueue application_queue; MessageQueue app_local_queue; From 9444d21c1273872d8fe1b2b24f7742845bd9f1a1 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 15:24:26 -0700 Subject: [PATCH 090/165] Remove baseband stats tracking code. It was half-baked, and is getting in the way of a major refactoring. --- firmware/baseband/baseband_thread.cpp | 15 --------------- firmware/baseband/baseband_thread.hpp | 3 --- firmware/baseband/event_m4.cpp | 3 +-- 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index 053b5a3a..2182cc9f 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -24,7 +24,6 @@ #include "dsp_types.hpp" #include "baseband.hpp" -#include "baseband_stats_collector.hpp" #include "baseband_sgpio.hpp" #include "baseband_dma.hpp" @@ -94,13 +93,6 @@ void BasebandThread::run() { ); //baseband::dma::allocate(4, 2048); - BasebandStatsCollector stats { - chSysGetIdleThread(), - thread_main, - thread_rssi, - chThdSelf() - }; - while(true) { // TODO: Place correct sampling rate into buffer returned here: const auto buffer_tmp = baseband::dma::wait_for_rx_buffer(); @@ -112,13 +104,6 @@ void BasebandThread::run() { if( baseband_processor ) { baseband_processor->execute(buffer); } - - stats.process(buffer, - [](const BasebandStatistics& statistics) { - const BasebandStatisticsMessage message { statistics }; - shared_memory.application_queue.push(message); - } - ); } } } diff --git a/firmware/baseband/baseband_thread.hpp b/firmware/baseband/baseband_thread.hpp index ab9f7bb8..67438709 100644 --- a/firmware/baseband/baseband_thread.hpp +++ b/firmware/baseband/baseband_thread.hpp @@ -40,9 +40,6 @@ public: return baseband::Direction::Receive; } - Thread* thread_main { nullptr }; - Thread* thread_rssi { nullptr }; - private: BasebandProcessor* baseband_processor { nullptr }; diff --git a/firmware/baseband/event_m4.cpp b/firmware/baseband/event_m4.cpp index d956f2c0..1490ee2a 100644 --- a/firmware/baseband/event_m4.cpp +++ b/firmware/baseband/event_m4.cpp @@ -54,8 +54,7 @@ Thread* EventDispatcher::thread_event_loop = nullptr; void EventDispatcher::run() { thread_event_loop = chThdSelf(); - baseband_thread.thread_main = chThdSelf(); - baseband_thread.thread_rssi = rssi_thread.start(NORMALPRIO + 10); + rssi_thread.start(NORMALPRIO + 10); baseband_thread.start(NORMALPRIO + 20); lpc43xx::creg::m0apptxevent::enable(); From 2b7e76361904576d7ead8a1ecaa3df4dcd428e24 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 15:27:23 -0700 Subject: [PATCH 091/165] Don't check EventDispatcher::thread_event_loop before using. If static methods are getting called, variable is already set. --- firmware/baseband/event_m4.hpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/firmware/baseband/event_m4.hpp b/firmware/baseband/event_m4.hpp index ad9871d1..596c253b 100644 --- a/firmware/baseband/event_m4.hpp +++ b/firmware/baseband/event_m4.hpp @@ -40,15 +40,11 @@ public: void request_stop(); static inline void events_flag(const eventmask_t events) { - if( thread_event_loop ) { - chEvtSignal(thread_event_loop, events); - } + chEvtSignal(thread_event_loop, events); } static inline void events_flag_isr(const eventmask_t events) { - if( thread_event_loop ) { - chEvtSignalI(thread_event_loop, events); - } + chEvtSignalI(thread_event_loop, events); } private: From f8a473d56b2f5ce323ee27976c664116573ed47b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 15:34:49 -0700 Subject: [PATCH 092/165] Change baseband, RSSI threads to be more RAII. --- firmware/baseband/baseband_thread.cpp | 20 +++++++++++++------- firmware/baseband/baseband_thread.hpp | 5 ++++- firmware/baseband/event_m4.cpp | 3 --- firmware/baseband/event_m4.hpp | 4 ++-- firmware/baseband/rssi_thread.cpp | 19 ++++++++++++++++--- firmware/baseband/rssi_thread.hpp | 5 ++++- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index 2182cc9f..6fc8a153 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -48,13 +48,23 @@ static baseband::SGPIO baseband_sgpio; WORKING_AREA(baseband_thread_wa, 4096); -Thread* BasebandThread::start(const tprio_t priority) { - return chThdCreateStatic(baseband_thread_wa, sizeof(baseband_thread_wa), +Thread* BasebandThread::thread = nullptr; + +BasebandThread::BasebandThread(const tprio_t priority) { + thread = chThdCreateStatic(baseband_thread_wa, sizeof(baseband_thread_wa), priority, ThreadBase::fn, this ); } +BasebandThread::~BasebandThread() { + if( thread ) { + chThdTerminate(thread); + chThdWait(thread); + thread = nullptr; + } +} + void BasebandThread::set_configuration(const BasebandConfiguration& new_configuration) { if( new_configuration.mode != baseband_configuration.mode ) { disable(); @@ -93,7 +103,7 @@ void BasebandThread::run() { ); //baseband::dma::allocate(4, 2048); - while(true) { + while( !chThdShouldTerminate() ) { // TODO: Place correct sampling rate into buffer returned here: const auto buffer_tmp = baseband::dma::wait_for_rx_buffer(); if( buffer_tmp ) { @@ -127,15 +137,11 @@ void BasebandThread::disable() { i2s::i2s0::tx_mute(); baseband::dma::disable(); baseband_sgpio.streaming_disable(); - rf::rssi::stop(); } } void BasebandThread::enable() { if( baseband_processor ) { - if( direction() == baseband::Direction::Receive ) { - rf::rssi::start(); - } baseband_sgpio.configure(direction()); baseband::dma::enable(direction()); baseband_sgpio.streaming_enable(); diff --git a/firmware/baseband/baseband_thread.hpp b/firmware/baseband/baseband_thread.hpp index 67438709..82862049 100644 --- a/firmware/baseband/baseband_thread.hpp +++ b/firmware/baseband/baseband_thread.hpp @@ -30,7 +30,8 @@ class BasebandThread : public ThreadBase { public: - Thread* start(const tprio_t priority); + BasebandThread(const tprio_t priority); + ~BasebandThread(); void on_message(const Message* const message); @@ -41,6 +42,8 @@ public: } private: + static Thread* thread; + BasebandProcessor* baseband_processor { nullptr }; BasebandConfiguration baseband_configuration; diff --git a/firmware/baseband/event_m4.cpp b/firmware/baseband/event_m4.cpp index 1490ee2a..0ef97bba 100644 --- a/firmware/baseband/event_m4.cpp +++ b/firmware/baseband/event_m4.cpp @@ -54,9 +54,6 @@ Thread* EventDispatcher::thread_event_loop = nullptr; void EventDispatcher::run() { thread_event_loop = chThdSelf(); - rssi_thread.start(NORMALPRIO + 10); - baseband_thread.start(NORMALPRIO + 20); - lpc43xx::creg::m0apptxevent::enable(); while(is_running) { diff --git a/firmware/baseband/event_m4.hpp b/firmware/baseband/event_m4.hpp index 596c253b..f0a7e5b4 100644 --- a/firmware/baseband/event_m4.hpp +++ b/firmware/baseband/event_m4.hpp @@ -50,8 +50,8 @@ public: private: static Thread* thread_event_loop; - BasebandThread baseband_thread; - RSSIThread rssi_thread; + BasebandThread baseband_thread { NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; bool is_running = true; diff --git a/firmware/baseband/rssi_thread.cpp b/firmware/baseband/rssi_thread.cpp index 0bf15334..465e1d1f 100644 --- a/firmware/baseband/rssi_thread.cpp +++ b/firmware/baseband/rssi_thread.cpp @@ -30,20 +30,32 @@ WORKING_AREA(rssi_thread_wa, 128); -Thread* RSSIThread::start(const tprio_t priority) { - return chThdCreateStatic(rssi_thread_wa, sizeof(rssi_thread_wa), +Thread* RSSIThread::thread = nullptr; + +RSSIThread::RSSIThread(const tprio_t priority) { + thread = chThdCreateStatic(rssi_thread_wa, sizeof(rssi_thread_wa), priority, ThreadBase::fn, this ); } +RSSIThread::~RSSIThread() { + if( thread ) { + chThdTerminate(thread); + chThdWait(thread); + thread = nullptr; + } +} + void RSSIThread::run() { rf::rssi::init(); rf::rssi::dma::allocate(4, 400); RSSIStatisticsCollector stats; - while(true) { + rf::rssi::start(); + + while( !chThdShouldTerminate() ) { // TODO: Place correct sampling rate into buffer returned here: const auto buffer_tmp = rf::rssi::dma::wait_for_buffer(); const rf::rssi::buffer_t buffer { @@ -59,5 +71,6 @@ void RSSIThread::run() { ); } + rf::rssi::stop(); rf::rssi::dma::free(); } diff --git a/firmware/baseband/rssi_thread.hpp b/firmware/baseband/rssi_thread.hpp index 5233ddd5..46a0031b 100644 --- a/firmware/baseband/rssi_thread.hpp +++ b/firmware/baseband/rssi_thread.hpp @@ -30,11 +30,14 @@ class RSSIThread : public ThreadBase { public: - Thread* start(const tprio_t priority); + RSSIThread(const tprio_t priority); + ~RSSIThread(); private: void run() override; + static Thread* thread; + const uint32_t sampling_rate { 400000 }; }; From 9188bb9ee9ba9e353228716ec726ace9f72b1e15 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 24 Jun 2016 15:46:53 -0700 Subject: [PATCH 093/165] Remove thread pointer checking. --- firmware/baseband/baseband_thread.cpp | 8 +++----- firmware/baseband/rssi_thread.cpp | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index 6fc8a153..27d4b033 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -58,11 +58,9 @@ BasebandThread::BasebandThread(const tprio_t priority) { } BasebandThread::~BasebandThread() { - if( thread ) { - chThdTerminate(thread); - chThdWait(thread); - thread = nullptr; - } + chThdTerminate(thread); + chThdWait(thread); + thread = nullptr; } void BasebandThread::set_configuration(const BasebandConfiguration& new_configuration) { diff --git a/firmware/baseband/rssi_thread.cpp b/firmware/baseband/rssi_thread.cpp index 465e1d1f..81be13ec 100644 --- a/firmware/baseband/rssi_thread.cpp +++ b/firmware/baseband/rssi_thread.cpp @@ -40,11 +40,9 @@ RSSIThread::RSSIThread(const tprio_t priority) { } RSSIThread::~RSSIThread() { - if( thread ) { - chThdTerminate(thread); - chThdWait(thread); - thread = nullptr; - } + chThdTerminate(thread); + chThdWait(thread); + thread = nullptr; } void RSSIThread::run() { From bb32ef5321f35b623ed90426b4e6f323d4028fc5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 25 Jun 2016 10:53:16 -0700 Subject: [PATCH 094/165] Bracket BasebandThread loop with enable/disable code. --- firmware/baseband/baseband_thread.cpp | 24 ++++++++---------------- firmware/baseband/baseband_thread.hpp | 3 --- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index 27d4b033..0f575ad6 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -101,6 +101,10 @@ void BasebandThread::run() { ); //baseband::dma::allocate(4, 2048); + baseband_sgpio.configure(direction()); + baseband::dma::enable(direction()); + baseband_sgpio.streaming_enable(); + while( !chThdShouldTerminate() ) { // TODO: Place correct sampling rate into buffer returned here: const auto buffer_tmp = baseband::dma::wait_for_rx_buffer(); @@ -114,6 +118,10 @@ void BasebandThread::run() { } } } + + i2s::i2s0::tx_mute(); + baseband::dma::disable(); + baseband_sgpio.streaming_disable(); } BasebandProcessor* BasebandThread::create_processor(const int32_t mode) { @@ -129,19 +137,3 @@ BasebandProcessor* BasebandThread::create_processor(const int32_t mode) { default: return nullptr; } } - -void BasebandThread::disable() { - if( baseband_processor ) { - i2s::i2s0::tx_mute(); - baseband::dma::disable(); - baseband_sgpio.streaming_disable(); - } -} - -void BasebandThread::enable() { - if( baseband_processor ) { - baseband_sgpio.configure(direction()); - baseband::dma::enable(direction()); - baseband_sgpio.streaming_enable(); - } -} diff --git a/firmware/baseband/baseband_thread.hpp b/firmware/baseband/baseband_thread.hpp index 82862049..ce09a51b 100644 --- a/firmware/baseband/baseband_thread.hpp +++ b/firmware/baseband/baseband_thread.hpp @@ -52,9 +52,6 @@ private: BasebandProcessor* create_processor(const int32_t mode); - void disable(); - void enable(); - void set_configuration(const BasebandConfiguration& new_configuration); }; From 74c8429f75f8249241f0558f289cd54d196b61dc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 25 Jun 2016 10:57:16 -0700 Subject: [PATCH 095/165] Take processor as argument to BasebandThread. Remove lots of dependency on specific processors. Reduce state by removing processor switching from BasebandThread. --- firmware/baseband/baseband_thread.cpp | 60 ++++----------------------- firmware/baseband/baseband_thread.hpp | 15 +++---- 2 files changed, 14 insertions(+), 61 deletions(-) diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index 0f575ad6..0784d9bd 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -31,15 +31,6 @@ #include "i2s.hpp" using namespace lpc43xx; -#include "proc_am_audio.hpp" -#include "proc_nfm_audio.hpp" -#include "proc_wfm_audio.hpp" -#include "proc_ais.hpp" -#include "proc_wideband_spectrum.hpp" -#include "proc_tpms.hpp" -#include "proc_ert.hpp" -#include "proc_capture.hpp" - #include "portapack_shared_memory.hpp" #include @@ -50,7 +41,13 @@ WORKING_AREA(baseband_thread_wa, 4096); Thread* BasebandThread::thread = nullptr; -BasebandThread::BasebandThread(const tprio_t priority) { +BasebandThread::BasebandThread( + uint32_t sampling_rate, + BasebandProcessor* const baseband_processor, + const tprio_t priority +) : baseband_processor { baseband_processor }, + sampling_rate { sampling_rate } +{ thread = chThdCreateStatic(baseband_thread_wa, sizeof(baseband_thread_wa), priority, ThreadBase::fn, this @@ -63,33 +60,6 @@ BasebandThread::~BasebandThread() { thread = nullptr; } -void BasebandThread::set_configuration(const BasebandConfiguration& new_configuration) { - if( new_configuration.mode != baseband_configuration.mode ) { - disable(); - - // TODO: Timing problem around disabling DMA and nulling and deleting old processor - auto old_p = baseband_processor; - baseband_processor = nullptr; - delete old_p; - - baseband_processor = create_processor(new_configuration.mode); - - enable(); - } - - baseband_configuration = new_configuration; -} - -void BasebandThread::on_message(const Message* const message) { - if( message->id == Message::ID::BasebandConfiguration ) { - set_configuration(reinterpret_cast(message)->configuration); - } else { - if( baseband_processor ) { - baseband_processor->on_message(message); - } - } -} - void BasebandThread::run() { baseband_sgpio.init(); baseband::dma::init(); @@ -110,7 +80,7 @@ void BasebandThread::run() { const auto buffer_tmp = baseband::dma::wait_for_rx_buffer(); if( buffer_tmp ) { buffer_c8_t buffer { - buffer_tmp.p, buffer_tmp.count, baseband_configuration.sampling_rate + buffer_tmp.p, buffer_tmp.count, sampling_rate }; if( baseband_processor ) { @@ -123,17 +93,3 @@ void BasebandThread::run() { baseband::dma::disable(); baseband_sgpio.streaming_disable(); } - -BasebandProcessor* BasebandThread::create_processor(const int32_t mode) { - switch(mode) { - case 0: return new NarrowbandAMAudio(); - case 1: return new NarrowbandFMAudio(); - case 2: return new WidebandFMAudio(); - case 3: return new AISProcessor(); - case 4: return new WidebandSpectrum(); - case 5: return new TPMSProcessor(); - case 6: return new ERTProcessor(); - case 7: return new CaptureProcessor(); - default: return nullptr; - } -} diff --git a/firmware/baseband/baseband_thread.hpp b/firmware/baseband/baseband_thread.hpp index ce09a51b..3263b4f1 100644 --- a/firmware/baseband/baseband_thread.hpp +++ b/firmware/baseband/baseband_thread.hpp @@ -30,10 +30,12 @@ class BasebandThread : public ThreadBase { public: - BasebandThread(const tprio_t priority); + BasebandThread( + uint32_t sampling_rate, + BasebandProcessor* const baseband_processor, + const tprio_t priority + ); ~BasebandThread(); - - void on_message(const Message* const message); // This getter should die, it's just here to leak information to code that // isn't in the right place to begin with. @@ -45,14 +47,9 @@ private: static Thread* thread; BasebandProcessor* baseband_processor { nullptr }; - - BasebandConfiguration baseband_configuration; + uint32_t sampling_rate; void run() override; - - BasebandProcessor* create_processor(const int32_t mode); - - void set_configuration(const BasebandConfiguration& new_configuration); }; #endif/*__BASEBAND_THREAD_H__*/ From 525e72ac86f4e209cd77b9b6e5941a64e4207d96 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 25 Jun 2016 11:11:37 -0700 Subject: [PATCH 096/165] Move Baseband/RSSI threads into Processors. --- firmware/baseband/event_m4.hpp | 2 -- firmware/baseband/proc_ais.hpp | 5 +++++ firmware/baseband/proc_am_audio.hpp | 5 +++++ firmware/baseband/proc_capture.hpp | 6 ++++++ firmware/baseband/proc_ert.hpp | 3 +++ firmware/baseband/proc_nfm_audio.hpp | 5 +++++ firmware/baseband/proc_tpms.hpp | 7 +++++++ firmware/baseband/proc_wfm_audio.hpp | 5 +++++ firmware/baseband/proc_wideband_spectrum.hpp | 8 ++++++++ 9 files changed, 44 insertions(+), 2 deletions(-) diff --git a/firmware/baseband/event_m4.hpp b/firmware/baseband/event_m4.hpp index f0a7e5b4..09b00fa2 100644 --- a/firmware/baseband/event_m4.hpp +++ b/firmware/baseband/event_m4.hpp @@ -50,8 +50,6 @@ public: private: static Thread* thread_event_loop; - BasebandThread baseband_thread { NORMALPRIO + 20 }; - RSSIThread rssi_thread { NORMALPRIO + 10 }; bool is_running = true; diff --git a/firmware/baseband/proc_ais.hpp b/firmware/baseband/proc_ais.hpp index 966d739a..7fa0d40c 100644 --- a/firmware/baseband/proc_ais.hpp +++ b/firmware/baseband/proc_ais.hpp @@ -23,6 +23,7 @@ #define __PROC_AIS_H__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" #include "channel_decimator.hpp" #include "matched_filter.hpp" @@ -47,6 +48,10 @@ public: void execute(const buffer_c8_t& buffer) override; private: + static constexpr size_t baseband_fs = 2457600; + + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; + std::array dst; const buffer_c16_t dst_buffer { dst.data(), diff --git a/firmware/baseband/proc_am_audio.hpp b/firmware/baseband/proc_am_audio.hpp index 051f1703..08cca3e5 100644 --- a/firmware/baseband/proc_am_audio.hpp +++ b/firmware/baseband/proc_am_audio.hpp @@ -23,6 +23,8 @@ #define __PROC_AM_AUDIO_H__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" +#include "rssi_thread.hpp" #include "dsp_decimate.hpp" #include "dsp_demodulate.hpp" @@ -44,6 +46,9 @@ private: static constexpr size_t decim_2_decimation_factor = 4; static constexpr size_t channel_filter_decimation_factor = 1; + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; + std::array dst; const buffer_c16_t dst_buffer { dst.data(), diff --git a/firmware/baseband/proc_capture.hpp b/firmware/baseband/proc_capture.hpp index e975d99c..c2b48b0c 100644 --- a/firmware/baseband/proc_capture.hpp +++ b/firmware/baseband/proc_capture.hpp @@ -23,6 +23,9 @@ #define __PROC_CAPTURE_HPP__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" +#include "rssi_thread.hpp" + #include "dsp_decimate.hpp" #include "spectrum_collector.hpp" @@ -45,6 +48,9 @@ private: static constexpr size_t baseband_fs = 4000000; static constexpr auto spectrum_rate_hz = 50.0f; + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; + std::array dst; const buffer_c16_t dst_buffer { dst.data(), diff --git a/firmware/baseband/proc_ert.hpp b/firmware/baseband/proc_ert.hpp index 9c0663c9..dc0a9ecc 100644 --- a/firmware/baseband/proc_ert.hpp +++ b/firmware/baseband/proc_ert.hpp @@ -23,6 +23,7 @@ #define __PROC_ERT_H__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" #include "channel_decimator.hpp" @@ -61,6 +62,8 @@ private: const size_t samples_per_symbol = channel_sampling_rate / symbol_rate; const float clock_recovery_rate = symbol_rate * 2; + BasebandThread baseband_thread { baseband_sampling_rate, this, NORMALPRIO + 20 }; + clock_recovery::ClockRecovery clock_recovery { clock_recovery_rate, symbol_rate, { 1.0f / 18.0f }, [this](const float symbol) { this->consume_symbol(symbol); } diff --git a/firmware/baseband/proc_nfm_audio.hpp b/firmware/baseband/proc_nfm_audio.hpp index 164e0b45..f4529a73 100644 --- a/firmware/baseband/proc_nfm_audio.hpp +++ b/firmware/baseband/proc_nfm_audio.hpp @@ -23,6 +23,8 @@ #define __PROC_NFM_AUDIO_H__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" +#include "rssi_thread.hpp" #include "dsp_decimate.hpp" #include "dsp_demodulate.hpp" @@ -41,6 +43,9 @@ public: private: static constexpr size_t baseband_fs = 3072000; + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; + std::array dst; const buffer_c16_t dst_buffer { dst.data(), diff --git a/firmware/baseband/proc_tpms.hpp b/firmware/baseband/proc_tpms.hpp index ba3294d2..bc1c0b3f 100644 --- a/firmware/baseband/proc_tpms.hpp +++ b/firmware/baseband/proc_tpms.hpp @@ -23,6 +23,8 @@ #define __PROC_TPMS_H__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" +#include "rssi_thread.hpp" #include "channel_decimator.hpp" #include "matched_filter.hpp" @@ -62,6 +64,11 @@ public: void execute(const buffer_c8_t& buffer) override; private: + static constexpr size_t baseband_fs = 2457600; + + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; + std::array dst; const buffer_c16_t dst_buffer { dst.data(), diff --git a/firmware/baseband/proc_wfm_audio.hpp b/firmware/baseband/proc_wfm_audio.hpp index 9752f90a..446990f5 100644 --- a/firmware/baseband/proc_wfm_audio.hpp +++ b/firmware/baseband/proc_wfm_audio.hpp @@ -23,6 +23,8 @@ #define __PROC_WFM_AUDIO_H__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" +#include "rssi_thread.hpp" #include "dsp_decimate.hpp" #include "dsp_demodulate.hpp" @@ -40,6 +42,9 @@ private: static constexpr size_t baseband_fs = 3072000; static constexpr auto spectrum_rate_hz = 50.0f; + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; + std::array dst; const buffer_c16_t dst_buffer { dst.data(), diff --git a/firmware/baseband/proc_wideband_spectrum.hpp b/firmware/baseband/proc_wideband_spectrum.hpp index 5a875735..7a650ee0 100644 --- a/firmware/baseband/proc_wideband_spectrum.hpp +++ b/firmware/baseband/proc_wideband_spectrum.hpp @@ -23,6 +23,9 @@ #define __PROC_WIDEBAND_SPECTRUM_H__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" +#include "rssi_thread.hpp" + #include "spectrum_collector.hpp" #include "message.hpp" @@ -38,6 +41,11 @@ public: void on_message(const Message* const message) override; private: + static constexpr size_t baseband_fs = 20000000; + + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; + SpectrumCollector channel_spectrum; std::array spectrum; From 1a5f3a4422b0f735d2b82b190c2f666d8d733d84 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 25 Jun 2016 11:14:28 -0700 Subject: [PATCH 097/165] Give new Processor to EventDispatcher. --- firmware/baseband/event_m4.cpp | 10 ++++++++-- firmware/baseband/event_m4.hpp | 3 +++ firmware/baseband/main.cpp | 23 ++++++++++++++--------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/firmware/baseband/event_m4.cpp b/firmware/baseband/event_m4.cpp index 0ef97bba..49c98caf 100644 --- a/firmware/baseband/event_m4.cpp +++ b/firmware/baseband/event_m4.cpp @@ -51,6 +51,12 @@ CH_IRQ_HANDLER(MAPP_IRQHandler) { Thread* EventDispatcher::thread_event_loop = nullptr; +EventDispatcher::EventDispatcher( + std::unique_ptr baseband_processor +) : baseband_processor { std::move(baseband_processor) } +{ +} + void EventDispatcher::run() { thread_event_loop = chThdSelf(); @@ -107,10 +113,10 @@ void EventDispatcher::on_message_shutdown(const ShutdownMessage&) { } void EventDispatcher::on_message_default(const Message* const message) { - baseband_thread.on_message(message); + baseband_processor->on_message(message); } void EventDispatcher::handle_spectrum() { const UpdateSpectrumMessage message; - baseband_thread.on_message(&message); + baseband_processor->on_message(&message); } diff --git a/firmware/baseband/event_m4.hpp b/firmware/baseband/event_m4.hpp index 09b00fa2..42b5d3b9 100644 --- a/firmware/baseband/event_m4.hpp +++ b/firmware/baseband/event_m4.hpp @@ -36,6 +36,8 @@ constexpr auto EVT_MASK_SPECTRUM = EVENT_MASK(1); class EventDispatcher { public: + EventDispatcher(std::unique_ptr baseband_processor); + void run(); void request_stop(); @@ -50,6 +52,7 @@ public: private: static Thread* thread_event_loop; + std::unique_ptr baseband_processor; bool is_running = true; diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index 5f8a7da0..5f817990 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -32,9 +32,14 @@ #include "touch_dma.hpp" -#include "baseband_thread.hpp" -#include "rssi_thread.hpp" -#include "baseband_processor.hpp" +#include "proc_am_audio.hpp" +#include "proc_nfm_audio.hpp" +#include "proc_wfm_audio.hpp" +#include "proc_ais.hpp" +#include "proc_wideband_spectrum.hpp" +#include "proc_tpms.hpp" +#include "proc_ert.hpp" +#include "proc_capture.hpp" #include "message_queue.hpp" @@ -85,6 +90,11 @@ static void init() { touch::dma::enable(); } +static void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} + static void halt() { port_disable(); while(true) { @@ -109,12 +119,7 @@ static void shutdown() { int main(void) { init(); - - /* TODO: Ensure DMAs are configured to point at first LLI in chain. */ - - EventDispatcher event_dispatcher; - event_dispatcher.run(); - + run(); shutdown(); return 0; From 500a651bcfa364511c8f4cf54ce69f2aa563578e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 11:53:58 -0700 Subject: [PATCH 098/165] Give Processors a run() function. So main() can call it, start a Processor linked in to the baseband binary. --- firmware/baseband/main.cpp | 16 +--------------- firmware/baseband/proc_ais.cpp | 7 +++++++ firmware/baseband/proc_am_audio.cpp | 7 +++++++ firmware/baseband/proc_capture.cpp | 7 +++++++ firmware/baseband/proc_ert.cpp | 7 +++++++ firmware/baseband/proc_nfm_audio.cpp | 7 +++++++ firmware/baseband/proc_tpms.cpp | 7 +++++++ firmware/baseband/proc_wfm_audio.cpp | 7 +++++++ firmware/baseband/proc_wideband_spectrum.cpp | 7 +++++++ 9 files changed, 57 insertions(+), 15 deletions(-) diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index 5f817990..2fa72999 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -28,19 +28,8 @@ #include "gpdma.hpp" -#include "event_m4.hpp" - #include "touch_dma.hpp" -#include "proc_am_audio.hpp" -#include "proc_nfm_audio.hpp" -#include "proc_wfm_audio.hpp" -#include "proc_ais.hpp" -#include "proc_wideband_spectrum.hpp" -#include "proc_tpms.hpp" -#include "proc_ert.hpp" -#include "proc_capture.hpp" - #include "message_queue.hpp" #include "utility.hpp" @@ -90,10 +79,7 @@ static void init() { touch::dma::enable(); } -static void run() { - EventDispatcher event_dispatcher { std::make_unique() }; - event_dispatcher.run(); -} +extern void run(); static void halt() { port_disable(); diff --git a/firmware/baseband/proc_ais.cpp b/firmware/baseband/proc_ais.cpp index 80452dd0..b5f95319 100644 --- a/firmware/baseband/proc_ais.cpp +++ b/firmware/baseband/proc_ais.cpp @@ -25,6 +25,8 @@ #include "dsp_fir_taps.hpp" +#include "event_m4.hpp" + AISProcessor::AISProcessor() { decim_0.configure(taps_11k0_decim_0.taps, 33554432); decim_1.configure(taps_11k0_decim_1.taps, 131072); @@ -62,3 +64,8 @@ void AISProcessor::payload_handler( const AISPacketMessage message { packet }; shared_memory.application_queue.push(message); } + +void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} diff --git a/firmware/baseband/proc_am_audio.cpp b/firmware/baseband/proc_am_audio.cpp index f4cb2fac..a35f0742 100644 --- a/firmware/baseband/proc_am_audio.cpp +++ b/firmware/baseband/proc_am_audio.cpp @@ -23,6 +23,8 @@ #include "audio_output.hpp" +#include "event_m4.hpp" + #include void NarrowbandAMAudio::execute(const buffer_c8_t& buffer) { @@ -105,3 +107,8 @@ void NarrowbandAMAudio::capture_config(const CaptureConfigMessage& message) { audio_output.set_stream(nullptr); } } + +void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} diff --git a/firmware/baseband/proc_capture.cpp b/firmware/baseband/proc_capture.cpp index 56f6a948..d68cae29 100644 --- a/firmware/baseband/proc_capture.cpp +++ b/firmware/baseband/proc_capture.cpp @@ -23,6 +23,8 @@ #include "dsp_fir_taps.hpp" +#include "event_m4.hpp" + #include "utility.hpp" CaptureProcessor::CaptureProcessor() { @@ -90,3 +92,8 @@ void CaptureProcessor::capture_config(const CaptureConfigMessage& message) { stream.reset(); } } + +void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} diff --git a/firmware/baseband/proc_ert.cpp b/firmware/baseband/proc_ert.cpp index e6ae439c..124c141c 100644 --- a/firmware/baseband/proc_ert.cpp +++ b/firmware/baseband/proc_ert.cpp @@ -23,6 +23,8 @@ #include "portapack_shared_memory.hpp" +#include "event_m4.hpp" + float ERTProcessor::abs(const complex8_t& v) { // const int16_t r = v.real() - offset_i; // const int16_t i = v.imag() - offset_q; @@ -101,3 +103,8 @@ void ERTProcessor::idm_handler( const ERTPacketMessage message { ert::Packet::Type::IDM, packet }; shared_memory.application_queue.push(message); } + +void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} diff --git a/firmware/baseband/proc_nfm_audio.cpp b/firmware/baseband/proc_nfm_audio.cpp index 122115fa..18280b7c 100644 --- a/firmware/baseband/proc_nfm_audio.cpp +++ b/firmware/baseband/proc_nfm_audio.cpp @@ -23,6 +23,8 @@ #include "audio_output.hpp" +#include "event_m4.hpp" + #include #include @@ -93,3 +95,8 @@ void NarrowbandFMAudio::capture_config(const CaptureConfigMessage& message) { audio_output.set_stream(nullptr); } } + +void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index 7c6c83d6..61a23739 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -23,6 +23,8 @@ #include "dsp_fir_taps.hpp" +#include "event_m4.hpp" + TPMSProcessor::TPMSProcessor() { decim_0.configure(taps_200k_decim_0.taps, 33554432); decim_1.configure(taps_200k_decim_1.taps, 131072); @@ -55,3 +57,8 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { }); } } + +void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} diff --git a/firmware/baseband/proc_wfm_audio.cpp b/firmware/baseband/proc_wfm_audio.cpp index 98de47b8..0bd8e068 100644 --- a/firmware/baseband/proc_wfm_audio.cpp +++ b/firmware/baseband/proc_wfm_audio.cpp @@ -23,6 +23,8 @@ #include "audio_output.hpp" +#include "event_m4.hpp" + #include void WidebandFMAudio::execute(const buffer_c8_t& buffer) { @@ -122,3 +124,8 @@ void WidebandFMAudio::capture_config(const CaptureConfigMessage& message) { audio_output.set_stream(nullptr); } } + +void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} diff --git a/firmware/baseband/proc_wideband_spectrum.cpp b/firmware/baseband/proc_wideband_spectrum.cpp index 399cf626..57268198 100644 --- a/firmware/baseband/proc_wideband_spectrum.cpp +++ b/firmware/baseband/proc_wideband_spectrum.cpp @@ -25,6 +25,8 @@ #include "dsp_fft.hpp" +#include "event_m4.hpp" + #include #include @@ -72,3 +74,8 @@ void WidebandSpectrum::on_message(const Message* const message) { break; } } + +void run() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); +} From cf5ac441ae84603c76967b65387278deb3a26d14 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 12:02:43 -0700 Subject: [PATCH 099/165] Add CMake firmware build system. --- firmware/CMakeLists.txt | 76 ++++ firmware/application/CMakeLists.txt | 307 ++++++++++++++++ firmware/baseband/CMakeLists.txt | 339 ++++++++++++++++++ firmware/bootstrap/CMakeLists.txt | 206 +++++++++++ .../boards/GSG_HACKRF_ONE/board.cmake | 9 + .../hal/platforms/LPC43xx_M0/platform.cmake | 17 + .../hal/platforms/LPC43xx_M4/platform.cmake | 17 + .../os/ports/GCC/ARMCMx/LPC43xx_M0/port.cmake | 21 ++ .../os/ports/GCC/ARMCMx/LPC43xx_M4/port.cmake | 21 ++ .../os/various/fatfs_bindings/fatfs.cmake | 10 + firmware/chibios/os/hal/hal.cmake | 29 ++ firmware/chibios/os/kernel/kernel.cmake | 27 ++ .../chibios/os/ports/GCC/ARMCMx/rules.cmake | 107 ++++++ firmware/chibios/test/test.cmake | 20 ++ firmware/toolchain-arm-cortex-m.cmake | 55 +++ 15 files changed, 1261 insertions(+) create mode 100644 firmware/CMakeLists.txt create mode 100644 firmware/application/CMakeLists.txt create mode 100644 firmware/baseband/CMakeLists.txt create mode 100644 firmware/bootstrap/CMakeLists.txt create mode 100644 firmware/chibios-portapack/boards/GSG_HACKRF_ONE/board.cmake create mode 100644 firmware/chibios-portapack/os/hal/platforms/LPC43xx_M0/platform.cmake create mode 100644 firmware/chibios-portapack/os/hal/platforms/LPC43xx_M4/platform.cmake create mode 100644 firmware/chibios-portapack/os/ports/GCC/ARMCMx/LPC43xx_M0/port.cmake create mode 100644 firmware/chibios-portapack/os/ports/GCC/ARMCMx/LPC43xx_M4/port.cmake create mode 100644 firmware/chibios-portapack/os/various/fatfs_bindings/fatfs.cmake create mode 100644 firmware/chibios/os/hal/hal.cmake create mode 100644 firmware/chibios/os/kernel/kernel.cmake create mode 100644 firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake create mode 100644 firmware/chibios/test/test.cmake create mode 100644 firmware/toolchain-arm-cortex-m.cmake diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt new file mode 100644 index 00000000..5cb85fa2 --- /dev/null +++ b/firmware/CMakeLists.txt @@ -0,0 +1,76 @@ +# Copyright 2016 Jared Boone +# +# 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. +# + +cmake_minimum_required(VERSION 2.8.9) +set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) + +project(portapack-h1-firmware) + +execute_process( + COMMAND git log -n 1 --format=%h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + RESULT_VARIABLE GIT_REVISION_FOUND + ERROR_QUIET + OUTPUT_VARIABLE GIT_REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if (GIT_REVISION_FOUND) + set(VERSION "unknown") +else (GIT_REVISION_FOUND) + set(VERSION ${GIT_REVISION}) +endif (GIT_REVISION_FOUND) + +set(COMMON ${PROJECT_SOURCE_DIR}/common) +set(CHIBIOS ${PROJECT_SOURCE_DIR}/chibios) +set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) + +set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu) +set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME}) +set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py) +set(LICENSE_PATH ${PROJECT_SOURCE_DIR}/../LICENSE) + +add_subdirectory(application) +add_subdirectory(baseband) +add_subdirectory(bootstrap) + +add_custom_target( + ${PROJECT_NAME}.bin + COMMAND ${MAKE_SPI_IMAGE} ${bootstrap_BINARY_DIR}/bootstrap.bin ${HACKRF_FIRMWARE_IMAGE} ${baseband_BINARY_DIR}/baseband.img ${application_BINARY_DIR}/application.bin ${PROJECT_NAME}.bin + DEPENDS bootstrap.bin baseband.img application.bin +) + +add_custom_target( + program + COMMAND dfu-util --device 1fc9:000c --download ${HACKRF_FIRMWARE_IMAGE} --reset + COMMAND sleep 1s + COMMAND hackrf_spiflash -w ${PROJECT_NAME}.bin + DEPENDS ${PROJECT_NAME}.bin +) + +# TODO: Bad hack to fix location of LICENSE file for tar. +add_custom_target( + release + COMMAND cp ${LICENSE_PATH} LICENSE + COMMAND cp ${HACKRF_FIRMWARE_IMAGE} ${HACKRF_FIRMWARE_FILENAME} + COMMAND tar -c -j -f ${PROJECT_NAME}-${GIT_REVISION}.tar.bz2 ${PROJECT_NAME}.bin ${HACKRF_FIRMWARE_FILENAME} LICENSE + COMMAND zip -9 -q ${PROJECT_NAME}-${GIT_REVISION}.zip ${PROJECT_NAME}.bin ${HACKRF_FIRMWARE_FILENAME} LICENSE + COMMAND rm -f LICENSE ${HACKRF_FIRMWARE_FILENAME} + DEPENDS ${PROJECT_NAME}.bin +) diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt new file mode 100644 index 00000000..27a3e33d --- /dev/null +++ b/firmware/application/CMakeLists.txt @@ -0,0 +1,307 @@ +# +# Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. +# + +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +enable_language(C CXX ASM) + +project(application) + +# Compiler options here. +set(USE_OPT "-Os --specs=nano.specs") + +# C specific options here (added to USE_OPT). +set(USE_COPT "-std=gnu99") + +# C++ specific options here (added to USE_OPT). +set(USE_CPPOPT "-std=c++11 -fno-rtti -fno-exceptions") + +# Enable this if you want the linker to remove unused code and data +set(USE_LINK_GC yes) + +# Linker extra options here. +set(USE_LDOPT) + +# Enable this if you want link time optimizations (LTO) +set(USE_LTO no) + +# If enabled, this option allows to compile the application in THUMB mode. +set(USE_THUMB yes) + +# Enable this if you want to see the full log while compiling. +set(USE_VERBOSE_COMPILE no) + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Enables the use of FPU on Cortex-M4 (no, softfp, hard). +set(USE_FPU no) + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Imported source files and paths +include(${CHIBIOS_PORTAPACK}/boards/GSG_HACKRF_ONE/board.cmake) +include(${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M0/platform.cmake) +include(${CHIBIOS}/os/hal/hal.cmake) +include(${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M0/port.cmake) +include(${CHIBIOS}/os/kernel/kernel.cmake) +include(${CHIBIOS_PORTAPACK}/os/various/fatfs_bindings/fatfs.cmake) +include(${CHIBIOS}/test/test.cmake) + +# Define linker script file here +set(LDSCRIPT ${PORTLD}/LPC43xx_M0.ld) + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +set(CSRC + ${PORTSRC} + ${KERNSRC} + ${TESTSRC} + ${HALSRC} + ${PLATFORMSRC} + ${BOARDSRC} + ${FATFSSRC} +) + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +set(CPPSRC + main.cpp + irq_lcd_frame.cpp + irq_controls.cpp + irq_rtc.cpp + ${COMMON}/event.cpp + event_m0.cpp + ${COMMON}/message_queue.cpp + ${COMMON}/hackrf_hal.cpp + portapack.cpp + ${COMMON}/portapack_shared_memory.cpp + baseband_api.cpp + ${COMMON}/portapack_persistent_memory.cpp + ${COMMON}/portapack_io.cpp + ${COMMON}/i2c_pp.cpp + spi_pp.cpp + clock_manager.cpp + si5351.cpp + ${COMMON}/wm8731.cpp + radio.cpp + baseband_cpld.cpp + tuning.cpp + rf_path.cpp + rffc507x.cpp + rffc507x_spi.cpp + max2837.cpp + max5864.cpp + debounce.cpp + touch.cpp + touch_adc.cpp + encoder.cpp + audio.cpp + ${COMMON}/lcd_ili9341.cpp + ${COMMON}/ui.cpp + ${COMMON}/ui_text.cpp + ${COMMON}/ui_widget.cpp + ${COMMON}/ui_painter.cpp + ${COMMON}/ui_focus.cpp + ui_navigation.cpp + ui_menu.cpp + ui_rssi.cpp + ui_channel.cpp + ui_audio.cpp + ui_font_fixed_8x16.cpp + ui_setup.cpp + ui_debug.cpp + ui_baseband_stats_view.cpp + ui_sd_card_status_view.cpp + ui_sd_card_debug.cpp + ui_console.cpp + ui_receiver.cpp + ui_record_view.cpp + ui_spectrum.cpp + recent_entries.cpp + receiver_model.cpp + spectrum_color_lut.cpp + analog_audio_app.cpp + ${COMMON}/ais_baseband.cpp + ${COMMON}/ais_packet.cpp + ais_app.cpp + tpms_app.cpp + ${COMMON}/tpms_packet.cpp + ert_app.cpp + ${COMMON}/ert_packet.cpp + capture_app.cpp + sd_card.cpp + time.cpp + file.cpp + log_file.cpp + ${COMMON}/png_writer.cpp + capture_thread.cpp + ${COMMON}/manchester.cpp + string_format.cpp + temperature_logger.cpp + ${COMMON}/utility.cpp + ${COMMON}/chibios_cpp.cpp + ${COMMON}/debug.cpp + ${COMMON}/gcc.cpp + ${COMMON}/lfsr_random.cpp + core_control.cpp + ${COMMON}/cpld_max5.cpp + ${COMMON}/jtag.cpp + cpld_update.cpp + ${COMMON}/portapack_cpld_data.cpp +) + +# C sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(ACSRC) + +# C++ sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(ACPPSRC) + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(TCSRC) + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(TCPPSRC) + +# List ASM source files here +set(ASMSRC ${PORTASM}) + +set(INCDIR ${COMMON} ${PORTINC} ${KERNINC} ${TESTINC} + ${HALINC} ${PLATFORMINC} ${BOARDINC} + ${FATFSINC} + ${CHIBIOS}/os/various +) + +# +# Project, sources and paths +############################################################################## + +############################################################################## +# Compiler settings +# + +# TODO: Entertain using MCU=cortex-m0.small-multiply for LPC43xx M0 core. +# However, on GCC-ARM-Embedded 4.9 2015q2, it seems to produce non-functional +# binaries. +set(MCU cortex-m0) + +# ARM-specific options here +set(AOPT) + +# THUMB-specific options here +set(TOPT "-mthumb -DTHUMB") + +# Define C warning options here +set(CWARN "-Wall -Wextra -Wstrict-prototypes") + +# Define C++ warning options here +set(CPPWARN "-Wall -Wextra") + +# +# Compiler settings +############################################################################## + +############################################################################## +# Start of default section +# + +# List all default C defines here, like -D_DEBUG=1 +# TODO: Switch -DCRT0_INIT_DATA depending on load from RAM or SPIFI? +# NOTE: _RANDOM_TCC to kill a GCC 4.9.3 error with std::max argument types +set(DDEFS -DLPC43XX -DLPC43XX_M0 -D__NEWLIB__ -DHACKRF_ONE -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D_RANDOM_TCC=0 -DGIT_REVISION=\"${GIT_REVISION}\") + +# List all default ASM defines here, like -D_DEBUG=1 +set(DADEFS) + +# List all default directories to look for include files here +set(DINCDIR) + +# List the default directory to look for the libraries here +set(DLIBDIR) + +# List all default libraries here +set(DLIBS) + +# +# End of default section +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +set(UDEFS) + +# Define ASM defines here +set(UADEFS) + +# List all user directories here +set(UINCDIR) + +# List the user directory to look for the libraries here +set(ULIBDIR) + +# List all user libraries here +set(ULIBS) + +# +# End of user defines +############################################################################## + +set(RULESPATH ${CHIBIOS}/os/ports/GCC/ARMCMx) +include(${RULESPATH}/rules.cmake) + +############################################################################## + +add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC} ${LDSCRIPT}) +add_definitions(${DEFS}) +include_directories(. ${INCDIR}) +link_directories(${LLIBDIR}) +target_link_libraries(${PROJECT_NAME}.elf ${LIBS}) + +add_custom_target( + ${PROJECT_NAME}.bin + COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin + DEPENDS ${PROJECT_NAME}.elf +) diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt new file mode 100644 index 00000000..a7108bf3 --- /dev/null +++ b/firmware/baseband/CMakeLists.txt @@ -0,0 +1,339 @@ +# +# Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. +# + +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +enable_language(C CXX ASM) + +project(baseband) + +# Compiler options here. +set(USE_OPT "-O3 -falign-functions=16 -fno-math-errno --specs=nano.specs") + +# C specific options here (added to USE_OPT). +set(USE_COPT "-std=gnu99") + +# C++ specific options here (added to USE_OPT). +set(USE_CPPOPT "-std=c++11 -fno-rtti -fno-exceptions") + +# Enable this if you want the linker to remove unused code and data +set(USE_LINK_GC yes) + +# Linker extra options here. +set(USE_LDOPT) + +# Enable this if you want link time optimizations (LTO) +set(USE_LTO no) + +# If enabled, this option allows to compile the application in THUMB mode. +set(USE_THUMB yes) + +# Enable this if you want to see the full log while compiling. +set(USE_VERBOSE_COMPILE no) + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Enables the use of FPU on Cortex-M4 (no, softfp, hard). +set(USE_FPU hard) + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Imported source files and paths +include(${CHIBIOS_PORTAPACK}/boards/GSG_HACKRF_ONE/board.cmake) +include(${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M4/platform.cmake) +include(${CHIBIOS}/os/hal/hal.cmake) +include(${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M4/port.cmake) +include(${CHIBIOS}/os/kernel/kernel.cmake) + +include(${CHIBIOS}/test/test.cmake) + +# Define linker script file here +set(LDSCRIPT ${PORTLD}/LPC43xx_M4.ld) + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +set(CSRC + ${PORTSRC} + ${KERNSRC} + ${TESTSRC} + ${HALSRC} + ${PLATFORMSRC} + ${BOARDSRC} +) + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +set(CPPSRC + main.cpp + ${COMMON}/message_queue.cpp + ${COMMON}/event.cpp + event_m4.cpp + ${COMMON}/thread_wait.cpp + ${COMMON}/gpdma.cpp + baseband_dma.cpp + ${COMMON}/baseband_sgpio.cpp + ${COMMON}/portapack_shared_memory.cpp + baseband_thread.cpp + baseband_processor.cpp + baseband_stats_collector.cpp + dsp_decimate.cpp + dsp_demodulate.cpp + matched_filter.cpp + spectrum_collector.cpp + stream_input.cpp + dsp_squelch.cpp + clock_recovery.cpp + packet_builder.cpp + ${COMMON}/dsp_fft.cpp + ${COMMON}/dsp_fir_taps.cpp + ${COMMON}/dsp_iir.cpp + fxpt_atan2.cpp + rssi.cpp + rssi_dma.cpp + rssi_thread.cpp + audio_compressor.cpp + audio_output.cpp + audio_dma.cpp + audio_stats_collector.cpp + touch_dma.cpp + ${COMMON}/utility.cpp + ${COMMON}/chibios_cpp.cpp + ${COMMON}/debug.cpp + ${COMMON}/gcc.cpp +) + +# C sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(ACSRC) + +# C++ sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(ACPPSRC) + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(TCSRC) + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(TCPPSRC) + +# List ASM source files here +set(ASMSRC ${PORTASM}) + +set(INCDIR ${COMMON} ${PORTINC} ${KERNINC} ${TESTINC} + ${HALINC} ${PLATFORMINC} ${BOARDINC} + ${CHIBIOS}/os/various +) + +# +# Project, sources and paths +############################################################################## + +############################################################################## +# Compiler settings +# + +set(MCU cortex-m4) + +# ARM-specific options here +set(AOPT) + +# THUMB-specific options here +set(TOPT "-mthumb -DTHUMB") + +# Define C warning options here +set(CWARN "-Wall -Wextra -Wstrict-prototypes") + +# Define C++ warning options here +set(CPPWARN "-Wall -Wextra") + +# +# Compiler settings +############################################################################## + +############################################################################## +# Start of default section +# + +# List all default C defines here, like -D_DEBUG=1 +# TODO: Switch -DCRT0_INIT_DATA depending on load from RAM or SPIFI? +# NOTE: _RANDOM_TCC to kill a GCC 4.9.3 error with std::max argument types +set(DDEFS -DLPC43XX -DLPC43XX_M4 -D__NEWLIB__ -DHACKRF_ONE -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D_RANDOM_TCC=0 -DGIT_REVISION=\"${GIT_REVISION}\") + +# List all default ASM defines here, like -D_DEBUG=1 +set(DADEFS) + +# List all default directories to look for include files here +set(DINCDIR) + +# List the default directory to look for the libraries here +set(DLIBDIR) + +# List all default libraries here +set(DLIBS) + +# +# End of default section +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +set(UDEFS) + +# Define ASM defines here +set(UADEFS) + +# List all user directories here +set(UINCDIR) + +# List the user directory to look for the libraries here +set(ULIBDIR) + +# List all user libraries here +set(ULIBS) + +# +# End of user defines +############################################################################## + +set(RULESPATH ${CHIBIOS}/os/ports/GCC/ARMCMx) +include(${RULESPATH}/rules.cmake) + +####################################################################### + +add_library(${PROJECT_NAME} OBJECT ${CSRC} ${CPPSRC} ${ASMSRC}) +include_directories(. ${INCDIR}) + +####################################################################### + +set(BASEBAND_IMAGES) + +macro(DeclareTargets) + include(${RULESPATH}/rules.cmake) + add_executable(${PROJECT_NAME}.elf $ ${MODE_CPPSRC} ${LDSCRIPT}) + add_definitions(${DEFS}) + include_directories(. ${INCDIR}) + link_directories(${LLIBDIR}) + target_link_libraries(${PROJECT_NAME}.elf ${LIBS}) + + add_custom_target( + ${PROJECT_NAME}.bin + COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin + DEPENDS ${PROJECT_NAME}.elf + ) + + set(BASEBAND_IMAGES ${BASEBAND_IMAGES} ${PROJECT_NAME}.bin) +endmacro() + +### AIS + +project(baseband_ais) +set(MODE_CPPSRC + proc_ais.cpp +) +DeclareTargets() + +### AM Audio + +project(baseband_am_audio) +set(MODE_CPPSRC + proc_am_audio.cpp +) +DeclareTargets() + +### Capture + +project(baseband_capture) +set(MODE_CPPSRC + proc_capture.cpp +) +DeclareTargets() + +### ERT + +project(baseband_ert) +set(MODE_CPPSRC + proc_ert.cpp +) +DeclareTargets() + +### NFM Audio + +project(baseband_nfm_audio) +set(MODE_CPPSRC + proc_nfm_audio.cpp +) +DeclareTargets() + +### TPMS + +project(baseband_tpms) +set(MODE_CPPSRC + proc_tpms.cpp +) +DeclareTargets() + +### WFM Audio + +project(baseband_wfm_audio) +set(MODE_CPPSRC + proc_wfm_audio.cpp +) +DeclareTargets() + +### Wideband Spectrum + +project(baseband_wideband_spectrum) +set(MODE_CPPSRC + proc_wideband_spectrum.cpp +) +DeclareTargets() + +####################################################################### + +add_custom_target( + baseband.img + COMMAND cat ${BASEBAND_IMAGES} >baseband.img + DEPENDS ${BASEBAND_IMAGES} +) diff --git a/firmware/bootstrap/CMakeLists.txt b/firmware/bootstrap/CMakeLists.txt new file mode 100644 index 00000000..27c1271d --- /dev/null +++ b/firmware/bootstrap/CMakeLists.txt @@ -0,0 +1,206 @@ +# +# Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. +# + +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +enable_language(C CXX ASM) + +project(bootstrap) + +# Compiler options here. +set(USE_OPT "-Os -falign-functions=16 -fno-math-errno --specs=nano.specs") + +# C specific options here (added to USE_OPT). +set(USE_COPT "-std=gnu99") + +# C++ specific options here (added to USE_OPT). +set(USE_CPPOPT "-std=c++11 -fno-rtti -fno-exceptions") + +# Enable this if you want the linker to remove unused code and data +set(USE_LINK_GC yes) + +# Linker extra options here. +set(USE_LDOPT) + +# Enable this if you want link time optimizations (LTO) +set(USE_LTO no) + +# If enabled, this option allows to compile the application in THUMB mode. +set(USE_THUMB yes) + +# Enable this if you want to see the full log while compiling. +set(USE_VERBOSE_COMPILE no) + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Enables the use of FPU on Cortex-M4 (no, softfp, hard). +set(USE_FPU no) + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Define linker script file here +set(LDSCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/m4.ld) + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +set(CSRC + bootstrap.c +) + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +set(CPPSRC) + +# C sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(ACSRC) + +# C++ sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(ACPPSRC) + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(TCSRC) + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +set(TCPPSRC) + +# List ASM source files here +set(ASMSRC startup_ARMCM4.S) + +set(INCDIR + ${CHIBIOS}/os/ports/common/ARMCMx/CMSIS/include + ${CHIBIOS}/os/ports/common/ARMCMx + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M4 +) + +# +# Project, sources and paths +############################################################################## + +############################################################################## +# Compiler settings +# + +set(MCU cortex-m4) + +# ARM-specific options here +set(AOPT) + +# THUMB-specific options here +set(TOPT "-mthumb -DTHUMB") + +# Define C warning options here +set(CWARN "-Wall -Wextra -Wstrict-prototypes") + +# Define C++ warning options here +set(CPPWARN "-Wall -Wextra") + +# +# Compiler settings +############################################################################## + +############################################################################## +# Start of default section +# + +# List all default C defines here, like -D_DEBUG=1 +# TODO: Switch -DCRT0_INIT_DATA depending on load from RAM or SPIFI? +# NOTE: _RANDOM_TCC to kill a GCC 4.9.3 error with std::max argument types +set(DDEFS -DLPC43XX -DLPC43XX_M4 -D__START=main -DGIT_REVISION=\"${GIT_REVISION}\") + +# List all default ASM defines here, like -D_DEBUG=1 +set(DADEFS) + +# List all default directories to look for include files here +set(DINCDIR) + +# List the default directory to look for the libraries here +set(DLIBDIR) + +# List all default libraries here +set(DLIBS) + +# +# End of default section +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +set(UDEFS) + +# Define ASM defines here +set(UADEFS) + +# List all user directories here +set(UINCDIR) + +# List the user directory to look for the libraries here +set(ULIBDIR) + +# List all user libraries here +set(ULIBS) + +# +# End of user defines +############################################################################## + +set(RULESPATH ${CHIBIOS}/os/ports/GCC/ARMCMx) +include(${RULESPATH}/rules.cmake) + +############################################################################## + +add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC} ${LDSCRIPT}) +add_definitions(${DEFS}) +include_directories(. ${INCDIR}) +link_directories(${LLIBDIR}) +target_link_libraries(${PROJECT_NAME}.elf ${LIBS}) + +add_custom_target( + ${PROJECT_NAME}.bin + COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin + DEPENDS ${PROJECT_NAME}.elf +) diff --git a/firmware/chibios-portapack/boards/GSG_HACKRF_ONE/board.cmake b/firmware/chibios-portapack/boards/GSG_HACKRF_ONE/board.cmake new file mode 100644 index 00000000..5befc3f1 --- /dev/null +++ b/firmware/chibios-portapack/boards/GSG_HACKRF_ONE/board.cmake @@ -0,0 +1,9 @@ +# List of all the board related files. +set(BOARDSRC + ${CHIBIOS_PORTAPACK}/boards/GSG_HACKRF_ONE/board.c +) + +# Required include directories +set(BOARDINC + ${CHIBIOS_PORTAPACK}/boards/GSG_HACKRF_ONE +) diff --git a/firmware/chibios-portapack/os/hal/platforms/LPC43xx_M0/platform.cmake b/firmware/chibios-portapack/os/hal/platforms/LPC43xx_M0/platform.cmake new file mode 100644 index 00000000..d1566907 --- /dev/null +++ b/firmware/chibios-portapack/os/hal/platforms/LPC43xx_M0/platform.cmake @@ -0,0 +1,17 @@ +# List of all the LPC43xx M0 platform files. +set(PLATFORMSRC + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M0/hal_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/gpt_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/i2c_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/pal_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/rtc_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/sdc_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/serial_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/spi_lld.c +) + +# Required include directories +set(PLATFORMINC + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M0 + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx +) diff --git a/firmware/chibios-portapack/os/hal/platforms/LPC43xx_M4/platform.cmake b/firmware/chibios-portapack/os/hal/platforms/LPC43xx_M4/platform.cmake new file mode 100644 index 00000000..20952c85 --- /dev/null +++ b/firmware/chibios-portapack/os/hal/platforms/LPC43xx_M4/platform.cmake @@ -0,0 +1,17 @@ +# List of all the LPC43xx M4 platform files. +set(PLATFORMSRC + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M4/hal_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/gpt_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/i2c_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/pal_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/rtc_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/sdc_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/serial_lld.c + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx/spi_lld.c +) + +# Required include directories +set(PLATFORMINC + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M4 + ${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx +) diff --git a/firmware/chibios-portapack/os/ports/GCC/ARMCMx/LPC43xx_M0/port.cmake b/firmware/chibios-portapack/os/ports/GCC/ARMCMx/LPC43xx_M0/port.cmake new file mode 100644 index 00000000..336f9102 --- /dev/null +++ b/firmware/chibios-portapack/os/ports/GCC/ARMCMx/LPC43xx_M0/port.cmake @@ -0,0 +1,21 @@ +# List of the ChibiOS/RT Cortex-M0 LPC43xx port files. +set(PORTSRC + ${CHIBIOS}/os/ports/GCC/ARMCMx/crt0.c + ${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M0/vectors.c + ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c + ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v6m.c + ${CHIBIOS}/os/ports/common/ARMCMx/nvic.c +) + +set(PORTASM) + +set(PORTINC + ${CHIBIOS}/os/ports/common/ARMCMx/CMSIS/include + ${CHIBIOS}/os/ports/common/ARMCMx + ${CHIBIOS}/os/ports/GCC/ARMCMx + ${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M0 +) + +set(PORTLD + ${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M0/ld +) diff --git a/firmware/chibios-portapack/os/ports/GCC/ARMCMx/LPC43xx_M4/port.cmake b/firmware/chibios-portapack/os/ports/GCC/ARMCMx/LPC43xx_M4/port.cmake new file mode 100644 index 00000000..482e107b --- /dev/null +++ b/firmware/chibios-portapack/os/ports/GCC/ARMCMx/LPC43xx_M4/port.cmake @@ -0,0 +1,21 @@ +# List of the ChibiOS/RT Cortex-M4 LPC43xx port files. +set(PORTSRC + ${CHIBIOS}/os/ports/GCC/ARMCMx/crt0.c + ${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M4/vectors.c + ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c + ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v7m.c + ${CHIBIOS}/os/ports/common/ARMCMx/nvic.c +) + +set(PORTASM) + +set(PORTINC + ${CHIBIOS}/os/ports/common/ARMCMx/CMSIS/include + ${CHIBIOS}/os/ports/common/ARMCMx + ${CHIBIOS}/os/ports/GCC/ARMCMx + ${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M4 +) + +set(PORTLD + ${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M4/ld +) diff --git a/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs.cmake b/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs.cmake new file mode 100644 index 00000000..389f5d14 --- /dev/null +++ b/firmware/chibios-portapack/os/various/fatfs_bindings/fatfs.cmake @@ -0,0 +1,10 @@ +# FATFS files. +set(FATFSSRC + ${CHIBIOS_PORTAPACK}/os/various/fatfs_bindings/fatfs_diskio.c + ${CHIBIOS_PORTAPACK}/os/various/fatfs_bindings/fatfs_syscall.c + ${CHIBIOS_PORTAPACK}/ext/fatfs/src/ff.c +) + +set(FATFSINC + ${CHIBIOS_PORTAPACK}/ext/fatfs/src +) diff --git a/firmware/chibios/os/hal/hal.cmake b/firmware/chibios/os/hal/hal.cmake new file mode 100644 index 00000000..07440d15 --- /dev/null +++ b/firmware/chibios/os/hal/hal.cmake @@ -0,0 +1,29 @@ +# List of all the ChibiOS/RT HAL files, there is no need to remove the files +# from this list, you can disable parts of the HAL by editing halconf.h. +set(HALSRC + ${CHIBIOS}/os/hal/src/hal.c + ${CHIBIOS}/os/hal/src/adc.c + ${CHIBIOS}/os/hal/src/can.c + ${CHIBIOS}/os/hal/src/ext.c + ${CHIBIOS}/os/hal/src/gpt.c + ${CHIBIOS}/os/hal/src/i2c.c + ${CHIBIOS}/os/hal/src/icu.c + ${CHIBIOS}/os/hal/src/mac.c + ${CHIBIOS}/os/hal/src/mmc_spi.c + ${CHIBIOS}/os/hal/src/mmcsd.c + ${CHIBIOS}/os/hal/src/pal.c + ${CHIBIOS}/os/hal/src/pwm.c + ${CHIBIOS}/os/hal/src/rtc.c + ${CHIBIOS}/os/hal/src/sdc.c + ${CHIBIOS}/os/hal/src/serial.c + ${CHIBIOS}/os/hal/src/serial_usb.c + ${CHIBIOS}/os/hal/src/spi.c + ${CHIBIOS}/os/hal/src/tm.c + ${CHIBIOS}/os/hal/src/uart.c + ${CHIBIOS}/os/hal/src/usb.c +) + +# Required include directories +set(HALINC + ${CHIBIOS}/os/hal/include +) diff --git a/firmware/chibios/os/kernel/kernel.cmake b/firmware/chibios/os/kernel/kernel.cmake new file mode 100644 index 00000000..f3c629e0 --- /dev/null +++ b/firmware/chibios/os/kernel/kernel.cmake @@ -0,0 +1,27 @@ +# List of all the ChibiOS/RT kernel files, there is no need to remove the files +# from this list, you can disable parts of the kernel by editing chconf.h. +set(KERNSRC + ${CHIBIOS}/os/kernel/src/chsys.c + ${CHIBIOS}/os/kernel/src/chdebug.c + ${CHIBIOS}/os/kernel/src/chlists.c + ${CHIBIOS}/os/kernel/src/chvt.c + ${CHIBIOS}/os/kernel/src/chschd.c + ${CHIBIOS}/os/kernel/src/chthreads.c + ${CHIBIOS}/os/kernel/src/chdynamic.c + ${CHIBIOS}/os/kernel/src/chregistry.c + ${CHIBIOS}/os/kernel/src/chsem.c + ${CHIBIOS}/os/kernel/src/chmtx.c + ${CHIBIOS}/os/kernel/src/chcond.c + ${CHIBIOS}/os/kernel/src/chevents.c + ${CHIBIOS}/os/kernel/src/chmsg.c + ${CHIBIOS}/os/kernel/src/chmboxes.c + ${CHIBIOS}/os/kernel/src/chqueues.c + ${CHIBIOS}/os/kernel/src/chmemcore.c + ${CHIBIOS}/os/kernel/src/chheap.c + ${CHIBIOS}/os/kernel/src/chmempools.c +) + +# Required include directories +set(KERNINC + ${CHIBIOS}/os/kernel/include +) diff --git a/firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake b/firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake new file mode 100644 index 00000000..fef8f450 --- /dev/null +++ b/firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake @@ -0,0 +1,107 @@ +# ARM Cortex-Mx common makefile scripts and rules. + +############################################################################## +# Processing options coming from the upper Makefile. +# + +# Compiler options +set(OPT ${USE_OPT}) +set(COPT ${USE_COPT}) +set(CPPOPT ${USE_CPPOPT}) + +# Garbage collection +if(USE_LINK_GC STREQUAL "yes") + set(OPT "${OPT} -ffunction-sections -fdata-sections -fno-common") + set(LDOPT ",--gc-sections") +else() + set(LDOPT) +endif() + +# Linker extra options +if(DEFINED USE_LDOPT) + set(LDOPT "${LDOPT},${USE_LDOPT}") +endif() + +# Link time optimizations +if(USE_LTO STREQUAL "yes") + set(OPT "${OPT} -flto") +endif() + +# FPU-related options +if(NOT DEFINED USE_FPU) + set(USE_FPU no) +endif() +if(NOT USE_FPU STREQUAL "no") + set(OPT "${OPT} -mfloat-abi=${USE_FPU} -mfpu=fpv4-sp-d16 -fsingle-precision-constant") + set(DDEFS ${DDEFS} -DCORTEX_USE_FPU=TRUE) + set(DADEFS ${DADEFS} -DCORTEX_USE_FPU=TRUE) +else() + set(DDEFS ${DDEFS} -DCORTEX_USE_FPU=FALSE) + set(DADEFS ${DADEFS} -DCORTEX_USE_FPU=FALSE) +endif() + +# Source files groups and paths +if(USE_THUMB STREQUAL "yes") + set(TCSRC ${TCSRC} ${CSRC}) + set(TCPPSRC ${TCPPSRC} ${CPPSRC}) +else() + set(ACSRC ${ACSRC} ${CSRC}) + set(ACPPSRC ${ACPPSRC} ${CPPSRC}) +endif() +set(ASRC ${ACSRC} ${ACPPSRC}) +set(TSRC ${TCSRC} ${TCPPSRC}) + +# Paths +set(IINCDIR ${INCDIR} ${DINCDIR} ${UINCDIR}) +set(LLIBDIR ${DLIBDIR} ${ULIBDIR}) + +# Macros +set(DEFS ${DDEFS} ${UDEFS}) +set(ADEFS ${DADEFS} ${UADEFS}) + +# Libs +set(LIBS ${DLIBS} ${ULIBS}) + +# Various settings +set(MCFLAGS -mcpu=${MCU}) +set(ODFLAGS "-x --syms") +set(ASFLAGS "${MCFLAGS} ${ADEFS}") +set(ASXFLAGS "${MCFLAGS} ${ADEFS}") +set(CFLAGS "${MCFLAGS} ${OPT} ${COPT} ${CWARN}") +set(CPPFLAGS "${MCFLAGS} ${OPT} ${CPPOPT} ${CPPWARN}") +set(LDFLAGS "-nostartfiles -Wl,-Map=${PROJECT_NAME}.map,--cref,--no-warn-mismatch,--library-path=${RULESPATH},--script=${LDSCRIPT}${LDOPT}") + +# Thumb interwork enabled only if needed because it kills performance. +if(DEFINED TSRC) + set(CFLAGS "${CFLAGS}") + set(CPPFLAGS "${CPPFLAGS}") + set(ASFLAGS "${ASFLAGS}") + set(DEFS ${DEFS} -DTHUMB_PRESENT) + set(ADEFS ${ADEFS} -DTHUMB_PRESENT) + if(DEFINED ASRC) + # Mixed ARM and THUMB mode. + set(CFLAGS "${CFLAGS} -mthumb-interwork") + set(CPPFLAGS "${CPPFLAGS} -mthumb-interwork") + set(ASFLAGS "${ASFLAGS} -mthumb-interwork") + set(LDFLAGS "${LDFLAGS} -mthumb-interwork") + else() + # Pure THUMB mode, THUMB C code cannot be called by ARM asm code directly. + set(CFLAGS "${CFLAGS} -mno-thumb-interwork") + set(CPPFLAGS "${CPPFLAGS} -mno-thumb-interwork") + set(ASFLAGS "${ASFLAGS} -mno-thumb-interwork -mthumb") + set(LDFLAGS "${LDFLAGS} -mno-thumb-interwork -mthumb") + set(DEFS ${DEFS} -DTHUMB_NO_INTERWORKING) + set(ADEFS ${ADEFS} -DTHUMB_NO_INTERWORKING) + endif() +else() + # Pure ARM mode + set(CFLAGS "${CFLAGS} -mno-thumb-interwork") + set(CPPFLAGS "${CPPFLAGS} -mno-thumb-interwork") + set(ASFLAGS "${ASFLAGS} -mno-thumb-interwork") + set(LDFLAGS "${LDFLAGS} -mno-thumb-interwork") +endif() + +set(CMAKE_C_FLAGS "${CFLAGS} ${TOPT}") +set(CMAKE_CXX_FLAGS "${CPPFLAGS} ${TOPT}") +set(CMAKE_AS_FLAGS "${ASFLAGS} ${TOPT}") +set(CMAKE_EXE_LINKER_FLAGS "${LDFLAGS}") diff --git a/firmware/chibios/test/test.cmake b/firmware/chibios/test/test.cmake new file mode 100644 index 00000000..ddfa74e1 --- /dev/null +++ b/firmware/chibios/test/test.cmake @@ -0,0 +1,20 @@ +# List of all the ChibiOS/RT test files. +set(TESTSRC + ${CHIBIOS}/test/test.c + ${CHIBIOS}/test/testthd.c + ${CHIBIOS}/test/testsem.c + ${CHIBIOS}/test/testmtx.c + ${CHIBIOS}/test/testmsg.c + ${CHIBIOS}/test/testmbox.c + ${CHIBIOS}/test/testevt.c + ${CHIBIOS}/test/testheap.c + ${CHIBIOS}/test/testpools.c + ${CHIBIOS}/test/testdyn.c + ${CHIBIOS}/test/testqueues.c + ${CHIBIOS}/test/testbmk.c +) + +# Required include directories +set(TESTINC + ${CHIBIOS}/test +) diff --git a/firmware/toolchain-arm-cortex-m.cmake b/firmware/toolchain-arm-cortex-m.cmake new file mode 100644 index 00000000..033fb185 --- /dev/null +++ b/firmware/toolchain-arm-cortex-m.cmake @@ -0,0 +1,55 @@ +# Copyright 2014 Jared Boone +# +# This file is part of PortaPack. +# This file was borrowed from HackRF. +# +# 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. +# + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR arm) + +include(CMakeForceCompiler) + +CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU) +CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-file-name=libc.a + OUTPUT_VARIABLE CMAKE_INSTALL_PREFIX + OUTPUT_STRIP_TRAILING_WHITESPACE +) +get_filename_component(CMAKE_INSTALL_PREFIX + "${CMAKE_INSTALL_PREFIX}" PATH +) +get_filename_component(CMAKE_INSTALL_PREFIX + "${CMAKE_INSTALL_PREFIX}/.." REALPATH +) +set(CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE FILEPATH + "Install path prefix, prepended onto install directories.") + +message(STATUS "Cross-compiling with the gcc-arm-embedded toolchain") +message(STATUS "Toolchain prefix: ${CMAKE_INSTALL_PREFIX}") + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +#set(CMAKE_LD ${CMAKE_INSTALL_PREFIX}/bin/ld CACHE INTERNAL "ld tool") +set(CMAKE_OBJCOPY ${CMAKE_INSTALL_PREFIX}/bin/objcopy CACHE INTERNAL "objcopy tool") + +set(CMAKE_FIND_ROOT_PATH ${CMAKE_INSTALL_PREFIX}) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) From 97760a2f9d4ff32743d2c71c5d8d135feb343204 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 12:04:10 -0700 Subject: [PATCH 100/165] Remove GNU Make files, now using CMake to build firmware. --- firmware/Makefile | 87 --------- firmware/application/Makefile | 329 ---------------------------------- firmware/baseband/Makefile | 290 ------------------------------ firmware/bootstrap/Makefile | 65 ------- 4 files changed, 771 deletions(-) delete mode 100644 firmware/Makefile delete mode 100755 firmware/application/Makefile delete mode 100755 firmware/baseband/Makefile delete mode 100644 firmware/bootstrap/Makefile diff --git a/firmware/Makefile b/firmware/Makefile deleted file mode 100644 index d735d3d7..00000000 --- a/firmware/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -# -# Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. -# - -PATH_BOOTSTRAP=bootstrap -PATH_APPLICATION=application -PATH_BASEBAND=baseband - -TARGET=portapack-h1-firmware - -TARGET_BOOTSTRAP=$(PATH_BOOTSTRAP)/bootstrap -TARGET_HACKRF_FIRMWARE=hackrf_one_usb_ram -TARGET_APPLICATION=$(PATH_APPLICATION)/build/application -TARGET_BASEBAND=$(PATH_BASEBAND)/build/baseband - -MAKE_SPI_IMAGE=tools/make_spi_image.py - -DFU_HACKRF=hackrf_one_usb_ram.dfu -LICENSE=../LICENSE - -GIT_REVISION=$(shell git log -n 1 --format=%h) - -CP=arm-none-eabi-objcopy - -all: $(TARGET).bin - -release: $(TARGET).bin $(DFU_HACKRF) $(LICENSE) - # TODO: Bad hack to fix location of LICENSE file for tar. - cp $(LICENSE) LICENSE - tar -c -j -f $(TARGET)-$(GIT_REVISION).tar.bz2 $(TARGET).bin $(DFU_HACKRF) LICENSE - zip -9 -q $(TARGET)-$(GIT_REVISION).zip $(TARGET).bin $(DFU_HACKRF) LICENSE - rm -f LICENSE - -program: $(TARGET).bin - dfu-util --device 1fc9:000c --download hackrf_one_usb_ram.dfu --reset - sleep 1s - hackrf_spiflash -w $(TARGET).bin - -$(TARGET).bin: $(MAKE_SPI_IMAGE) $(TARGET_BOOTSTRAP).bin $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_BASEBAND).bin $(TARGET_APPLICATION).bin - $(MAKE_SPI_IMAGE) $(TARGET_BOOTSTRAP).bin $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_BASEBAND).bin $(TARGET_APPLICATION).bin $(TARGET).bin - -$(TARGET_BOOTSTRAP).bin: $(TARGET_BOOTSTRAP).elf - $(CP) -O binary $(TARGET_BOOTSTRAP).elf $(TARGET_BOOTSTRAP).bin - -$(TARGET_BASEBAND).bin: $(TARGET_BASEBAND).elf - $(CP) -O binary $(TARGET_BASEBAND).elf $(TARGET_BASEBAND).bin - -$(TARGET_APPLICATION).bin: $(TARGET_APPLICATION).elf - $(CP) -O binary $(TARGET_APPLICATION).elf $(TARGET_APPLICATION).bin - -$(TARGET_BASEBAND).elf: always_check - @$(MAKE) -s -e GIT_REVISION=$(GIT_REVISION) -C $(PATH_BASEBAND) - -$(TARGET_APPLICATION).elf: always_check - @$(MAKE) -s -e GIT_REVISION=$(GIT_REVISION) -C $(PATH_APPLICATION) - -$(TARGET_BOOTSTRAP).elf: always_check - @$(MAKE) -s -e GIT_REVISION=$(GIT_REVISION) -C $(PATH_BOOTSTRAP) - -clean: - rm -f $(TARGET).bin - rm -f $(TARGET_BOOTSTRAP).bin - rm -f $(TARGET_BASEBAND).bin - rm -f $(TARGET_APPLICATION).bin - $(MAKE) -C $(PATH_BASEBAND) clean - $(MAKE) -C $(PATH_APPLICATION) clean - $(MAKE) -C $(PATH_BOOTSTRAP) clean - -always_check: - @true diff --git a/firmware/application/Makefile b/firmware/application/Makefile deleted file mode 100755 index 5f0c9e00..00000000 --- a/firmware/application/Makefile +++ /dev/null @@ -1,329 +0,0 @@ -# -# Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. -# - -############################################################################## -# Build global options -# NOTE: Can be overridden externally. -# - -# Compiler options here. -ifeq ($(USE_OPT),) - USE_OPT = -mthumb \ - -Os -ggdb3 \ - -ffunction-sections \ - -fdata-sections \ - -fno-builtin \ - -nostartfiles \ - --specs=nano.specs - #-fomit-frame-pointer -endif - -# C specific options here (added to USE_OPT). -ifeq ($(USE_COPT),) - USE_COPT = -std=gnu99 -endif - -# C++ specific options here (added to USE_OPT). -ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -std=c++11 -fno-rtti -fno-exceptions -endif - -# Enable this if you want the linker to remove unused code and data -ifeq ($(USE_LINK_GC),) - USE_LINK_GC = yes -endif - -# Linker extra options here. -ifeq ($(USE_LDOPT),) - USE_LDOPT = -endif - -# Enable this if you want link time optimizations (LTO) -ifeq ($(USE_LTO),) - USE_LTO = no -endif - -# If enabled, this option allows to compile the application in THUMB mode. -ifeq ($(USE_THUMB),) - USE_THUMB = yes -endif - -# Enable this if you want to see the full log while compiling. -ifeq ($(USE_VERBOSE_COMPILE),) - USE_VERBOSE_COMPILE = no -endif - -# -# Build global options -############################################################################## - -############################################################################## -# Architecture or project specific options -# - -# -# Architecture or project specific options -############################################################################## - -############################################################################## -# Project, sources and paths -# - -# Define project name here -PROJECT = application - -# Imported source files and paths -CHIBIOS = ../chibios -CHIBIOS_PORTAPACK = ../chibios-portapack -include $(CHIBIOS_PORTAPACK)/boards/GSG_HACKRF_ONE/board.mk -include $(CHIBIOS_PORTAPACK)/os/hal/platforms/LPC43xx_M0/platform.mk -include $(CHIBIOS)/os/hal/hal.mk -include $(CHIBIOS_PORTAPACK)/os/ports/GCC/ARMCMx/LPC43xx_M0/port.mk -include $(CHIBIOS)/os/kernel/kernel.mk -include $(CHIBIOS_PORTAPACK)/os/various/fatfs_bindings/fatfs.mk -include $(CHIBIOS)/test/test.mk - -# Define linker script file here -LDSCRIPT= $(PORTLD)/LPC43xx_M0.ld - -# C sources that can be compiled in ARM or THUMB mode depending on the global -# setting. -CSRC = $(PORTSRC) \ - $(KERNSRC) \ - $(TESTSRC) \ - $(HALSRC) \ - $(PLATFORMSRC) \ - $(BOARDSRC) \ - $(FATFSSRC) - - -# C++ sources that can be compiled in ARM or THUMB mode depending on the global -# setting. -CPPSRC = main.cpp \ - irq_lcd_frame.cpp \ - irq_controls.cpp \ - irq_rtc.cpp \ - event.cpp \ - event_m0.cpp \ - message_queue.cpp \ - hackrf_hal.cpp \ - portapack.cpp \ - portapack_shared_memory.cpp \ - baseband_api.cpp \ - portapack_persistent_memory.cpp \ - portapack_io.cpp \ - i2c_pp.cpp \ - spi_pp.cpp \ - clock_manager.cpp \ - si5351.cpp \ - wm8731.cpp \ - radio.cpp \ - baseband_cpld.cpp \ - tuning.cpp \ - rf_path.cpp \ - rffc507x.cpp \ - rffc507x_spi.cpp \ - max2837.cpp \ - max5864.cpp \ - debounce.cpp \ - touch.cpp \ - touch_adc.cpp \ - encoder.cpp \ - audio.cpp \ - lcd_ili9341.cpp \ - ui.cpp \ - ui_text.cpp \ - ui_widget.cpp \ - ui_painter.cpp \ - ui_focus.cpp \ - ui_navigation.cpp \ - ui_menu.cpp \ - ui_rssi.cpp \ - ui_channel.cpp \ - ui_audio.cpp \ - ui_font_fixed_8x16.cpp \ - ui_setup.cpp \ - ui_debug.cpp \ - ui_baseband_stats_view.cpp \ - ui_sd_card_status_view.cpp \ - ui_sd_card_debug.cpp \ - ui_console.cpp \ - ui_receiver.cpp \ - ui_record_view.cpp \ - ui_spectrum.cpp \ - recent_entries.cpp \ - receiver_model.cpp \ - spectrum_color_lut.cpp \ - analog_audio_app.cpp \ - ais_baseband.cpp \ - ../commom/ais_packet.cpp \ - ais_app.cpp \ - tpms_app.cpp \ - ../common/tpms_packet.cpp \ - ert_app.cpp \ - ../common/ert_packet.cpp \ - capture_app.cpp \ - sd_card.cpp \ - time.cpp \ - file.cpp \ - log_file.cpp \ - png_writer.cpp \ - capture_thread.cpp \ - manchester.cpp \ - string_format.cpp \ - temperature_logger.cpp \ - ../common/utility.cpp \ - ../common/chibios_cpp.cpp \ - ../common/debug.cpp \ - ../common/gcc.cpp \ - ../common/lfsr_random.cpp \ - core_control.cpp \ - cpld_max5.cpp \ - jtag.cpp \ - cpld_update.cpp \ - portapack_cpld_data.cpp - - -# C sources to be compiled in ARM mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -ACSRC = - -# C++ sources to be compiled in ARM mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -ACPPSRC = - -# C sources to be compiled in THUMB mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -TCSRC = - -# C sources to be compiled in THUMB mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -TCPPSRC = - -# List ASM source files here -ASMSRC = $(PORTASM) - -INCDIR = ../common $(PORTINC) $(KERNINC) $(TESTINC) \ - $(HALINC) $(PLATFORMINC) $(BOARDINC) \ - $(FATFSINC) \ - $(CHIBIOS)/os/various - -# -# Project, sources and paths -############################################################################## - -############################################################################## -# Compiler settings -# - -# TODO: Entertain using MCU=cortex-m0.small-multiply for LPC43xx M0 core. -# However, on GCC-ARM-Embedded 4.9 2015q2, it seems to produce non-functional -# binaries. -MCU = cortex-m0 - -#TRGT = arm-elf- -TRGT = arm-none-eabi- -CC = $(TRGT)gcc -CPPC = $(TRGT)g++ -# Enable loading with g++ only if you need C++ runtime support. -# NOTE: You can use C++ even without C++ support if you are careful. C++ -# runtime support makes code size explode. -#LD = $(TRGT)gcc -LD = $(TRGT)g++ -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -OD = $(TRGT)objdump -SZ = $(TRGT)size -HEX = $(CP) -O ihex -BIN = $(CP) -O binary - -# ARM-specific options here -AOPT = - -# THUMB-specific options here -TOPT = -mthumb -DTHUMB - -# Define C warning options here -CWARN = -Wall -Wextra -Wstrict-prototypes - -# Define C++ warning options here -CPPWARN = -Wall -Wextra - -# -# Compiler settings -############################################################################## - -############################################################################## -# Start of default section -# - -# List all default C defines here, like -D_DEBUG=1 -# TODO: Switch -DCRT0_INIT_DATA depending on load from RAM or SPIFI? -# NOTE: _RANDOM_TCC to kill a GCC 4.9.3 error with std::max argument types -DDEFS = -DLPC43XX -DLPC43XX_M0 -D__NEWLIB__ -DHACKRF_ONE \ - -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D_RANDOM_TCC=0 \ - -DGIT_REVISION=\"$(GIT_REVISION)\" - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################## - -############################################################################## -# Start of user section -# - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List all user directories here -UINCDIR = - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# -# End of user defines -############################################################################## - -RULESPATH = $(CHIBIOS)/os/ports/GCC/ARMCMx -include $(RULESPATH)/rules.mk diff --git a/firmware/baseband/Makefile b/firmware/baseband/Makefile deleted file mode 100755 index dda8f28c..00000000 --- a/firmware/baseband/Makefile +++ /dev/null @@ -1,290 +0,0 @@ -# -# Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. -# - -############################################################################## -# Build global options -# NOTE: Can be overridden externally. -# - -# Compiler options here. -ifeq ($(USE_OPT),) - USE_OPT = -mthumb \ - -O3 -ggdb3 \ - -ffunction-sections \ - -fdata-sections \ - -fno-builtin \ - -falign-functions=16 \ - -fno-math-errno \ - --specs=nano.specs - #-fomit-frame-pointer -endif - -# C specific options here (added to USE_OPT). -ifeq ($(USE_COPT),) - USE_COPT = -std=gnu99 -endif - -# C++ specific options here (added to USE_OPT). -ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -std=c++11 -fno-rtti -fno-exceptions -endif - -# Enable this if you want the linker to remove unused code and data -ifeq ($(USE_LINK_GC),) - USE_LINK_GC = yes -endif - -# Linker extra options here. -ifeq ($(USE_LDOPT),) - USE_LDOPT = -endif - -# Enable this if you want link time optimizations (LTO) -ifeq ($(USE_LTO),) - USE_LTO = no -endif - -# If enabled, this option allows to compile the application in THUMB mode. -ifeq ($(USE_THUMB),) - USE_THUMB = yes -endif - -# Enable this if you want to see the full log while compiling. -ifeq ($(USE_VERBOSE_COMPILE),) - USE_VERBOSE_COMPILE = no -endif - -# -# Build global options -############################################################################## - -############################################################################## -# Architecture or project specific options -# - -# Enables the use of FPU on Cortex-M4 (no, softfp, hard). -ifeq ($(USE_FPU),) - USE_FPU = hard -endif - -# -# Architecture or project specific options -############################################################################## - -############################################################################## -# Project, sources and paths -# - -# Define project name here -PROJECT = baseband - -# Imported source files and paths -CHIBIOS = ../chibios -CHIBIOS_PORTAPACK = ../chibios-portapack -include $(CHIBIOS_PORTAPACK)/boards/GSG_HACKRF_ONE/board.mk -include $(CHIBIOS_PORTAPACK)/os/hal/platforms/LPC43xx_M4/platform.mk -include $(CHIBIOS)/os/hal/hal.mk -include $(CHIBIOS_PORTAPACK)/os/ports/GCC/ARMCMx/LPC43xx_M4/port.mk -include $(CHIBIOS)/os/kernel/kernel.mk - -include $(CHIBIOS)/test/test.mk - -# Define linker script file here -LDSCRIPT= $(PORTLD)/LPC43xx_M4.ld - -# C sources that can be compiled in ARM or THUMB mode depending on the global -# setting. -CSRC = $(PORTSRC) \ - $(KERNSRC) \ - $(TESTSRC) \ - $(HALSRC) \ - $(PLATFORMSRC) \ - $(BOARDSRC) - - -# C++ sources that can be compiled in ARM or THUMB mode depending on the global -# setting. -CPPSRC = main.cpp \ - message_queue.cpp \ - event.cpp \ - event_m4.cpp \ - thread_wait.cpp \ - gpdma.cpp \ - baseband_dma.cpp \ - baseband_sgpio.cpp \ - portapack_shared_memory.cpp \ - baseband_thread.cpp \ - baseband_processor.cpp \ - baseband_stats_collector.cpp \ - dsp_decimate.cpp \ - dsp_demodulate.cpp \ - matched_filter.cpp \ - proc_am_audio.cpp \ - proc_nfm_audio.cpp \ - spectrum_collector.cpp \ - proc_wfm_audio.cpp \ - proc_ais.cpp \ - proc_wideband_spectrum.cpp \ - proc_tpms.cpp \ - proc_ert.cpp \ - proc_capture.cpp \ - stream_input.cpp \ - dsp_squelch.cpp \ - clock_recovery.cpp \ - packet_builder.cpp \ - dsp_fft.cpp \ - dsp_fir_taps.cpp \ - dsp_iir.cpp \ - fxpt_atan2.cpp \ - rssi.cpp \ - rssi_dma.cpp \ - rssi_thread.cpp \ - audio_compressor.cpp \ - audio_output.cpp \ - audio_dma.cpp \ - audio_stats_collector.cpp \ - touch_dma.cpp \ - ../common/utility.cpp \ - ../common/chibios_cpp.cpp \ - ../common/debug.cpp \ - ../common/gcc.cpp - -# C sources to be compiled in ARM mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -ACSRC = - -# C++ sources to be compiled in ARM mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -ACPPSRC = - -# C sources to be compiled in THUMB mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -TCSRC = - -# C sources to be compiled in THUMB mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -TCPPSRC = - -# List ASM source files here -ASMSRC = $(PORTASM) - -INCDIR = ../common $(PORTINC) $(KERNINC) $(TESTINC) \ - $(HALINC) $(PLATFORMINC) $(BOARDINC) \ - $(CHIBIOS)/os/various - -# -# Project, sources and paths -############################################################################## - -############################################################################## -# Compiler settings -# - -MCU = cortex-m4 - -#TRGT = arm-elf- -TRGT = arm-none-eabi- -CC = $(TRGT)gcc -CPPC = $(TRGT)g++ -# Enable loading with g++ only if you need C++ runtime support. -# NOTE: You can use C++ even without C++ support if you are careful. C++ -# runtime support makes code size explode. -#LD = $(TRGT)gcc -LD = $(TRGT)g++ -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -OD = $(TRGT)objdump -SZ = $(TRGT)size -HEX = $(CP) -O ihex -BIN = $(CP) -O binary - -# ARM-specific options here -AOPT = - -# THUMB-specific options here -TOPT = -mthumb -DTHUMB - -# Define C warning options here -CWARN = -Wall -Wextra -Wstrict-prototypes - -# Define C++ warning options here -CPPWARN = -Wall -Wextra - -# -# Compiler settings -############################################################################## - -############################################################################## -# Start of default section -# - -# List all default C defines here, like -D_DEBUG=1 -# TODO: Switch -DCRT0_INIT_DATA depending on load from RAM or SPIFI? -# NOTE: _RANDOM_TCC to kill a GCC 4.9.3 error with std::max argument types -DDEFS = -DLPC43XX -DLPC43XX_M4 -D__NEWLIB__ -DHACKRF_ONE \ - -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D_RANDOM_TCC=0 \ - -DGIT_REVISION=\"$(GIT_REVISION)\" - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################## - -############################################################################## -# Start of user section -# - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List all user directories here -UINCDIR = - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# -# End of user defines -############################################################################## - -RULESPATH = $(CHIBIOS)/os/ports/GCC/ARMCMx -include $(RULESPATH)/rules.mk diff --git a/firmware/bootstrap/Makefile b/firmware/bootstrap/Makefile deleted file mode 100644 index 85d3c738..00000000 --- a/firmware/bootstrap/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# -# Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. -# - -TARGET=bootstrap - -CC=arm-none-eabi-gcc -LD=arm-none-eabi-gcc -CP=arm-none-eabi-objcopy -OBJDUMP=arm-none-eabi-objdump - -CHIBIOS_PORTAPACK=../chibios-portapack -CHIBIOS=../chibios -INCLUDE=-I $(CHIBIOS)/os/ports/common/ARMCMx/CMSIS/include \ - -I $(CHIBIOS)/os/ports/common/ARMCMx \ - -I $(CHIBIOS_PORTAPACK)/os/hal/platforms/LPC43xx \ - -I $(CHIBIOS_PORTAPACK)/os/hal/platforms/LPC43xx_M4 -MCPU=cortex-m4 -CPUFLAGS=-mcpu=$(MCPU) -mthumb -mno-thumb-interwork -DTHUMB -DTHUMB_PRESENT -DTHUMB_NO_INTERWORKING - -COPT=-std=gnu99 \ - -Wall -Wextra -Wstrict-prototypes \ - $(CPUFLAGS) \ - -DLPC43XX -DLPC43XX_M4 \ - -DGIT_REVISION=\"$(GIT_REVISION)\" \ - -Os \ - -ffunction-sections \ - -fdata-sections \ - -fno-builtin --specs=nano.specs - -LDOPT=-nostartfiles \ - $(CPUFLAGS) \ - -D__START=main \ - -Wl,-Map=$(TARGET).map,--cref,--no-warn-mismatch,--library-path=.,--script=m4.ld,--gc-sections - -all: $(TARGET).elf - -$(TARGET).lst: $(TARGET).elf - $(OBJDUMP) -S $(TARGET).elf >$(TARGET).lst - -$(TARGET).elf: $(TARGET).o startup_ARMCM4.S - $(LD) $(LDOPT) $(LIB) -o $(TARGET).elf $(TARGET).o startup_ARMCM4.S - -$(TARGET).o: $(TARGET).c - $(CC) $(COPT) $(INCLUDE) -c -o $(TARGET).o $(TARGET).c - -clean: - rm -f $(TARGET).o $(TARGET).elf $(TARGET).bin $(TARGET).lst $(TARGET).map From f4c897946b0af33a7096b8e1d4b96b8a89375537 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 15:59:36 -0700 Subject: [PATCH 101/165] Add top-level CMake file. --- CMakeLists.txt | 42 +++++++++++++++++++++++++++++++++++++++++ firmware/CMakeLists.txt | 18 ------------------ 2 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..8750e289 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright 2016 Jared Boone +# +# 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. +# + +cmake_minimum_required(VERSION 2.8.9) +set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/firmware/toolchain-arm-cortex-m.cmake) + +project(portapack-h1) + +execute_process( + COMMAND git log -n 1 --format=%h + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + RESULT_VARIABLE GIT_REVISION_FOUND + ERROR_QUIET + OUTPUT_VARIABLE GIT_REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if (GIT_REVISION_FOUND) + set(VERSION "unknown") +else (GIT_REVISION_FOUND) + set(VERSION ${GIT_REVISION}) +endif (GIT_REVISION_FOUND) + +set(LICENSE_PATH ${CMAKE_CURRENT_LIST_DIR}/LICENSE) + +add_subdirectory(firmware) diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 5cb85fa2..5e906b36 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -18,25 +18,8 @@ # Boston, MA 02110-1301, USA. # -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - project(portapack-h1-firmware) -execute_process( - COMMAND git log -n 1 --format=%h - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - RESULT_VARIABLE GIT_REVISION_FOUND - ERROR_QUIET - OUTPUT_VARIABLE GIT_REVISION - OUTPUT_STRIP_TRAILING_WHITESPACE -) -if (GIT_REVISION_FOUND) - set(VERSION "unknown") -else (GIT_REVISION_FOUND) - set(VERSION ${GIT_REVISION}) -endif (GIT_REVISION_FOUND) - set(COMMON ${PROJECT_SOURCE_DIR}/common) set(CHIBIOS ${PROJECT_SOURCE_DIR}/chibios) set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) @@ -44,7 +27,6 @@ set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu) set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME}) set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py) -set(LICENSE_PATH ${PROJECT_SOURCE_DIR}/../LICENSE) add_subdirectory(application) add_subdirectory(baseband) From 946d45b31c27817af91a53197135aaf64c284fc3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 16:00:08 -0700 Subject: [PATCH 102/165] Adjust Travis for CMake system. --- .travis.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 53af9c24..b3c875dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,9 @@ before_script: script: # TODO: Introduce top-level Makefile, this is lame. - - pushd firmware/ + - mkdir build/ + - pushd build/ + - cmake .. - make release - popd @@ -33,5 +35,5 @@ addons: - lib32z1 artifacts: paths: - - $(ls firmware/portapack-h1-firmware-*.tar.bz2 | tr "\n" ":") - - $(ls firmware/portapack-h1-firmware-*.zip | tr "\n" ":") + - $(ls build/firmware/portapack-h1-firmware-*.tar.bz2 | tr "\n" ":") + - $(ls build/firmware/portapack-h1-firmware-*.zip | tr "\n" ":") From 01833ccb838bf0033368a05194750399800ecc3d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 16:45:41 -0700 Subject: [PATCH 103/165] Write all baseband binaries into tagged image file. --- firmware/CMakeLists.txt | 1 + firmware/baseband/CMakeLists.txt | 36 ++++++++-------- firmware/tools/make_image_chunk.py | 66 ++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 18 deletions(-) create mode 100755 firmware/tools/make_image_chunk.py diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 5e906b36..4d1f11d7 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -27,6 +27,7 @@ set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu) set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME}) set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py) +set(MAKE_IMAGE_CHUNK ${PROJECT_SOURCE_DIR}/tools/make_image_chunk.py) add_subdirectory(application) add_subdirectory(baseband) diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index a7108bf3..247731a3 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -249,7 +249,9 @@ include_directories(. ${INCDIR}) set(BASEBAND_IMAGES) -macro(DeclareTargets) +macro(DeclareTargets chunk_tag name) + project("baseband_${name}") + include(${RULESPATH}/rules.cmake) add_executable(${PROJECT_NAME}.elf $ ${MODE_CPPSRC} ${LDSCRIPT}) add_definitions(${DEFS}) @@ -263,72 +265,70 @@ macro(DeclareTargets) DEPENDS ${PROJECT_NAME}.elf ) - set(BASEBAND_IMAGES ${BASEBAND_IMAGES} ${PROJECT_NAME}.bin) + add_custom_target( + ${PROJECT_NAME}.img + COMMAND ${MAKE_IMAGE_CHUNK} ${PROJECT_NAME}.bin ${chunk_tag} ${PROJECT_NAME}.img + DEPENDS ${PROJECT_NAME}.bin + ) + + set(BASEBAND_IMAGES ${BASEBAND_IMAGES} ${PROJECT_NAME}.img) endmacro() ### AIS -project(baseband_ais) set(MODE_CPPSRC proc_ais.cpp ) -DeclareTargets() +DeclareTargets(PAIS ais) ### AM Audio -project(baseband_am_audio) set(MODE_CPPSRC proc_am_audio.cpp ) -DeclareTargets() +DeclareTargets(PAMA am_audio) ### Capture -project(baseband_capture) set(MODE_CPPSRC proc_capture.cpp ) -DeclareTargets() +DeclareTargets(PCAP capture) ### ERT -project(baseband_ert) set(MODE_CPPSRC proc_ert.cpp ) -DeclareTargets() +DeclareTargets(PERT ert) ### NFM Audio -project(baseband_nfm_audio) set(MODE_CPPSRC proc_nfm_audio.cpp ) -DeclareTargets() +DeclareTargets(PNFM nfm_audio) ### TPMS -project(baseband_tpms) set(MODE_CPPSRC proc_tpms.cpp ) -DeclareTargets() +DeclareTargets(PTPM tpms) ### WFM Audio -project(baseband_wfm_audio) set(MODE_CPPSRC proc_wfm_audio.cpp ) -DeclareTargets() +DeclareTargets(PWFM wfm_audio) ### Wideband Spectrum -project(baseband_wideband_spectrum) set(MODE_CPPSRC proc_wideband_spectrum.cpp ) -DeclareTargets() +DeclareTargets(PSPE wideband_spectrum) ####################################################################### diff --git a/firmware/tools/make_image_chunk.py b/firmware/tools/make_image_chunk.py new file mode 100755 index 00000000..825c6739 --- /dev/null +++ b/firmware/tools/make_image_chunk.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +# +# Copyright (C) 2015 Jared Boone, ShareBrained Technology, 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. +# + +import sys +import struct + +usage_message = """ +PortaPack image chunk writer + +Usage: +""" + +def read_image(path): + f = open(path, 'rb') + data = f.read() + f.close() + return data + +def write_image(data, path): + f = open(path, 'wb') + f.write(data) + f.close() + +if len(sys.argv) != 4: + print(usage_message) + sys.exit(-1) + +input_image = read_image(sys.argv[1]) +tag = sys.argv[2].encode() +output_path = sys.argv[3] + +if len(tag) != 4: + print(usage_message) + sys.exit(-2) + +input_image_max_length = 32768 +if len(input_image) > input_image_max_length: + raise RuntimeError('image size of %d exceeds device size of %d bytes' % (len(input_image), input_image_max_length)) +if (len(input_image) & 3) != 0: + raise RuntimeError('image size of %d is not multiple of four' % (len(input_image,))) + +output_image = bytearray() +output_image += struct.pack('<4sI', tag, len(input_image)) +output_image += input_image + +write_image(output_image, output_path) From 184eb9eb0dd24157ca065934895827f4ed78d146 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 19:35:51 -0700 Subject: [PATCH 104/165] Utility to strip HackRF firmware DFU header. --- firmware/tools/strip_dfu.py | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 firmware/tools/strip_dfu.py diff --git a/firmware/tools/strip_dfu.py b/firmware/tools/strip_dfu.py new file mode 100755 index 00000000..d3a9d8eb --- /dev/null +++ b/firmware/tools/strip_dfu.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# +# Copyright (C) 2015 Jared Boone, ShareBrained Technology, 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. +# + +import sys + +usage_message = """ +PortaPack DFU header stripper + +Usage: +""" + +def read_image(path): + f = open(path, 'rb') + data = f.read() + f.close() + return data + +def read_image_from_dfu(path): + data = read_image(path) + # Strip DFU header from file to get binary image. + return data[16:] + +def write_image(data, path): + f = open(path, 'wb') + f.write(data) + f.close() + +if len(sys.argv) != 3: + print(usage_message) + sys.exit(-1) + +dfu_image = read_image_from_dfu(sys.argv[1]) +output_path = sys.argv[2] + +write_image(dfu_image, output_path) From 61f954dbeb99cda6db10530badc187875052cef0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 19:36:23 -0700 Subject: [PATCH 105/165] Tweak make_image_chunk to produce empty chunk when argc == 2. --- firmware/tools/make_image_chunk.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/firmware/tools/make_image_chunk.py b/firmware/tools/make_image_chunk.py index 825c6739..53d9b14d 100755 --- a/firmware/tools/make_image_chunk.py +++ b/firmware/tools/make_image_chunk.py @@ -41,14 +41,18 @@ def write_image(data, path): f.write(data) f.close() -if len(sys.argv) != 4: +if len(sys.argv) == 4: + input_image = read_image(sys.argv[1]) + tag = sys.argv[2].encode() + output_path = sys.argv[3] +elif len(sys.argv) == 2: + input_image = bytearray() + tag = bytearray((0,) * 4) + output_path = sys.argv[1] +else: print(usage_message) sys.exit(-1) -input_image = read_image(sys.argv[1]) -tag = sys.argv[2].encode() -output_path = sys.argv[3] - if len(tag) != 4: print(usage_message) sys.exit(-2) From c3d81f1496eb6a63fdadbf6803baeb218fbe0579 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 19:37:05 -0700 Subject: [PATCH 106/165] Add HackRF factory firmware to basebands image. --- firmware/CMakeLists.txt | 1 + firmware/baseband/CMakeLists.txt | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 4d1f11d7..8d33aec5 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -26,6 +26,7 @@ set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu) set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME}) +set(STRIP_DFU ${PROJECT_SOURCE_DIR}/tools/strip_dfu.py) set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py) set(MAKE_IMAGE_CHUNK ${PROJECT_SOURCE_DIR}/tools/make_image_chunk.py) diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 247731a3..1bd437ec 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -330,6 +330,21 @@ set(MODE_CPPSRC ) DeclareTargets(PSPE wideband_spectrum) +### HackRF "factory" firmware + +add_custom_target( + hackrf.bin + COMMAND ${STRIP_DFU} ${HACKRF_FIRMWARE_IMAGE} hackrf.bin +) + +add_custom_target( + hackrf.img + COMMAND ${MAKE_IMAGE_CHUNK} hackrf.bin HRF1 hackrf.img + DEPENDS hackrf.bin +) + +set(BASEBAND_IMAGES ${BASEBAND_IMAGES} hackrf.img) + ####################################################################### add_custom_target( From f683980052e0f73f435a25161aea4f481d784dc3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 30 Jun 2016 19:37:32 -0700 Subject: [PATCH 107/165] Generate and append terminator chunk to basebands image. --- firmware/baseband/CMakeLists.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 1bd437ec..717d7b5b 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -345,10 +345,17 @@ add_custom_target( set(BASEBAND_IMAGES ${BASEBAND_IMAGES} hackrf.img) +### Terminator image + +add_custom_target( + terminator.img + COMMAND ${MAKE_IMAGE_CHUNK} terminator.img +) + ####################################################################### add_custom_target( baseband.img - COMMAND cat ${BASEBAND_IMAGES} >baseband.img - DEPENDS ${BASEBAND_IMAGES} + COMMAND cat ${BASEBAND_IMAGES} terminator.img >baseband.img + DEPENDS ${BASEBAND_IMAGES} terminator.img ) From 0e62876578749c12a9c963ef7dd7db9f0ac35081 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 1 Jul 2016 10:32:52 -0700 Subject: [PATCH 108/165] Add types for tagged data chunks in SPI flash. --- firmware/common/spi_image.hpp | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/firmware/common/spi_image.hpp b/firmware/common/spi_image.hpp index f8e71d62..a09c593c 100644 --- a/firmware/common/spi_image.hpp +++ b/firmware/common/spi_image.hpp @@ -30,6 +30,58 @@ namespace portapack { namespace spi_flash { +struct image_tag_t { + constexpr image_tag_t( + ) : c { 0, 0, 0, 0 } + { + } + + constexpr image_tag_t( + char c0, char c1, char c2, char c3 + ) : c { c0, c1, c2, c3 } + { + } + + image_tag_t& operator=(const image_tag_t& other) { + c[0] = other.c[0]; + c[1] = other.c[1]; + c[2] = other.c[2]; + c[3] = other.c[3]; + return *this; + } + + bool operator==(const image_tag_t& other) const { + return (c[0] == other.c[0]) && (c[1] == other.c[1]) && (c[2] == other.c[2]) && (c[3] == other.c[3]); + } + + operator bool() const { + return (c[0] != 0) || (c[1] != 0) || (c[2] != 0) || (c[3] != 0); + } + +private: + char c[4]; +}; + +constexpr image_tag_t image_tag_ais { 'P', 'A', 'I', 'S' }; +constexpr image_tag_t image_tag_am_audio { 'P', 'A', 'M', 'A' }; +constexpr image_tag_t image_tag_capture { 'P', 'C', 'A', 'P' }; +constexpr image_tag_t image_tag_ert { 'P', 'E', 'R', 'T' }; +constexpr image_tag_t image_tag_nfm_audio { 'P', 'N', 'F', 'M' }; +constexpr image_tag_t image_tag_tpms { 'P', 'T', 'P', 'M' }; +constexpr image_tag_t image_tag_wfm_audio { 'P', 'W', 'F', 'M' }; +constexpr image_tag_t image_tag_wideband_spectrum { 'P', 'S', 'P', 'E' }; +constexpr image_tag_t image_tag_hackrf { 'H', 'R', 'F', '1' }; + +struct chunk_t { + const image_tag_t tag; + const uint32_t length; + const uint8_t data[]; + + const chunk_t* next() const { + return reinterpret_cast(&data[length]); + } +}; + struct region_t { const size_t offset; const size_t size; From 97ba19af24b566f7cf71f20e8c7ca7b38ae0eb51 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 1 Jul 2016 10:37:22 -0700 Subject: [PATCH 109/165] Change M4 loader to use image tags. Also finish moving HackRF binary to tagged image region. --- firmware/CMakeLists.txt | 2 +- firmware/application/ais_app.cpp | 2 +- firmware/application/analog_audio_app.cpp | 14 ++++++++++-- firmware/application/baseband_api.cpp | 4 ++-- firmware/application/baseband_api.hpp | 2 +- firmware/application/capture_app.cpp | 2 +- firmware/application/core_control.cpp | 28 +++++++++++++++-------- firmware/application/core_control.hpp | 2 +- firmware/application/ert_app.cpp | 2 +- firmware/application/main.cpp | 2 +- firmware/application/tpms_app.cpp | 2 +- firmware/common/spi_image.hpp | 9 ++------ firmware/tools/make_spi_image.py | 23 +++++-------------- 13 files changed, 49 insertions(+), 45 deletions(-) diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 8d33aec5..68c1e2e2 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -36,7 +36,7 @@ add_subdirectory(bootstrap) add_custom_target( ${PROJECT_NAME}.bin - COMMAND ${MAKE_SPI_IMAGE} ${bootstrap_BINARY_DIR}/bootstrap.bin ${HACKRF_FIRMWARE_IMAGE} ${baseband_BINARY_DIR}/baseband.img ${application_BINARY_DIR}/application.bin ${PROJECT_NAME}.bin + COMMAND ${MAKE_SPI_IMAGE} ${bootstrap_BINARY_DIR}/bootstrap.bin ${baseband_BINARY_DIR}/baseband.img ${application_BINARY_DIR}/application.bin ${PROJECT_NAME}.bin DEPENDS bootstrap.bin baseband.img application.bin ) diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index 47da4bbd..39cc0e14 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -286,7 +286,7 @@ void AISRecentEntryDetailView::set_entry(const AISRecentEntry& entry) { } AISAppView::AISAppView(NavigationView&) { - baseband::run_image(portapack::spi_flash::baseband); + baseband::run_image(portapack::spi_flash::image_tag_ais); add_children({ { &label_channel, diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index a7304aca..fa2ba2e4 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -79,8 +79,6 @@ NBFMOptionsView::NBFMOptionsView( AnalogAudioView::AnalogAudioView( NavigationView& nav ) { - baseband::run_image(portapack::spi_flash::baseband); - add_children({ { &rssi, &channel, @@ -273,6 +271,18 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) { audio::output::mute(); record_view.stop(); + portapack::spi_flash::image_tag_t image_tag; + switch(modulation) { + case ReceiverModel::Mode::AMAudio: image_tag = portapack::spi_flash::image_tag_am_audio; break; + case ReceiverModel::Mode::NarrowbandFMAudio: image_tag = portapack::spi_flash::image_tag_nfm_audio; break; + case ReceiverModel::Mode::WidebandFMAudio: image_tag = portapack::spi_flash::image_tag_wfm_audio; break; + case ReceiverModel::Mode::SpectrumAnalysis: image_tag = portapack::spi_flash::image_tag_wideband_spectrum; break; + default: + return; + } + + baseband::run_image(image_tag); + const auto is_wideband_spectrum_mode = (modulation == ReceiverModel::Mode::SpectrumAnalysis); receiver_model.set_baseband_configuration({ .mode = toUType(modulation), diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 93dd0180..599a31b8 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -90,8 +90,8 @@ void stop() { send_message(&message); } -void run_image(const portapack::spi_flash::region_t image_region) { - m4_init(image_region, portapack::memory::map::m4_code); +void run_image(const portapack::spi_flash::image_tag_t image_tag) { + m4_init(image_tag, portapack::memory::map::m4_code); creg::m4txevent::enable(); } diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index f909b1a6..c12b08fd 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -55,7 +55,7 @@ struct WFMConfig { void start(BasebandConfiguration configuration); void stop(); -void run_image(const portapack::spi_flash::region_t image_region); +void run_image(const portapack::spi_flash::image_tag_t image_tag); void shutdown(); void spectrum_streaming_start(); diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 58af2526..9d1761a2 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -32,7 +32,7 @@ using namespace portapack; namespace ui { CaptureAppView::CaptureAppView(NavigationView& nav) { - baseband::run_image(portapack::spi_flash::baseband); + baseband::run_image(portapack::spi_flash::image_tag_capture); add_children({ { &rssi, diff --git a/firmware/application/core_control.cpp b/firmware/application/core_control.cpp index ebaca90d..a0fcccc8 100644 --- a/firmware/application/core_control.cpp +++ b/firmware/application/core_control.cpp @@ -38,17 +38,27 @@ using namespace lpc43xx; * I suppose I could force M4MEMMAP to an invalid memory reason which would * cause an exception and effectively halt the M4. But that feels gross. */ -void m4_init(const portapack::spi_flash::region_t from, const portapack::memory::region_t to) { - /* Initialize M4 code RAM */ - std::memcpy(reinterpret_cast(to.base()), from.base(), from.size); +void m4_init(const portapack::spi_flash::image_tag_t image_tag, const portapack::memory::region_t to) { + const portapack::spi_flash::chunk_t* chunk = reinterpret_cast(portapack::spi_flash::images.base()); + while(chunk->tag) { + if( chunk->tag == image_tag ) { + /* Initialize M4 code RAM */ + std::memcpy(reinterpret_cast(to.base()), &chunk->data[0], chunk->length); - /* M4 core is assumed to be sleeping with interrupts off, so we can mess - * with its address space and RAM without concern. - */ - LPC_CREG->M4MEMMAP = to.base(); + /* M4 core is assumed to be sleeping with interrupts off, so we can mess + * with its address space and RAM without concern. + */ + LPC_CREG->M4MEMMAP = to.base(); - /* Reset M4 core */ - LPC_RGU->RESET_CTRL[0] = (1 << 13); + /* Reset M4 core */ + LPC_RGU->RESET_CTRL[0] = (1 << 13); + + return; + } + chunk = chunk->next(); + } + + chDbgPanic("NoImg"); } void m4_request_shutdown() { diff --git a/firmware/application/core_control.hpp b/firmware/application/core_control.hpp index 3ec373fa..09737705 100644 --- a/firmware/application/core_control.hpp +++ b/firmware/application/core_control.hpp @@ -27,7 +27,7 @@ #include "memory_map.hpp" #include "spi_image.hpp" -void m4_init(const portapack::spi_flash::region_t from, const portapack::memory::region_t to); +void m4_init(const portapack::spi_flash::image_tag_t image_tag, const portapack::memory::region_t to); void m4_request_shutdown(); void m0_halt(); diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 467dbbc2..711f1284 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -121,7 +121,7 @@ void RecentEntriesView::draw( } ERTAppView::ERTAppView(NavigationView&) { - baseband::run_image(portapack::spi_flash::baseband); + baseband::run_image(portapack::spi_flash::image_tag_ert); add_children({ { &recent_entries_view, diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 5e52ee7e..93d496d3 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -91,7 +91,7 @@ int main(void) { sdcStop(&SDCD1); portapack::shutdown(); - m4_init(portapack::spi_flash::hackrf, portapack::memory::map::m4_code_hackrf); + m4_init(portapack::spi_flash::image_tag_hackrf, portapack::memory::map::m4_code_hackrf); m0_halt(); return 0; diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index f46b1549..a56c97e8 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -164,7 +164,7 @@ void RecentEntriesView::draw( } TPMSAppView::TPMSAppView(NavigationView&) { - baseband::run_image(portapack::spi_flash::baseband); + baseband::run_image(portapack::spi_flash::image_tag_tpms); add_children({ { &rssi, diff --git a/firmware/common/spi_image.hpp b/firmware/common/spi_image.hpp index a09c593c..e1143712 100644 --- a/firmware/common/spi_image.hpp +++ b/firmware/common/spi_image.hpp @@ -96,14 +96,9 @@ constexpr region_t bootstrap { .size = 0x10000, }; -constexpr region_t hackrf { +constexpr region_t images { .offset = 0x10000, - .size = 0x8000, -}; - -constexpr region_t baseband { - .offset = 0x20000, - .size = 0x8000, + .size = 0x30000, }; constexpr region_t application { diff --git a/firmware/tools/make_spi_image.py b/firmware/tools/make_spi_image.py index 646fa59e..d5d98328 100755 --- a/firmware/tools/make_spi_image.py +++ b/firmware/tools/make_spi_image.py @@ -26,7 +26,7 @@ import sys usage_message = """ PortaPack SPI flash image generator -Usage: +Usage: Where paths refer to the .bin files for each component project. """ @@ -36,25 +36,19 @@ def read_image(path): f.close() return data -def read_image_from_dfu(path): - data = read_image(path) - # Strip DFU header from file to get binary image. - return data[16:] - def write_image(data, path): f = open(path, 'wb') f.write(data) f.close() -if len(sys.argv) != 6: +if len(sys.argv) != 5: print(usage_message) sys.exit(-1) bootstrap_image = read_image(sys.argv[1]) -hackrf_image = read_image_from_dfu(sys.argv[2]) -baseband_image = read_image(sys.argv[3]) -application_image = read_image(sys.argv[4]) -output_path = sys.argv[5] +baseband_image = read_image(sys.argv[2]) +application_image = read_image(sys.argv[3]) +output_path = sys.argv[4] spi_size = 1048576 @@ -64,15 +58,10 @@ images = ( 'data': bootstrap_image, 'size': 0x10000, }, - { - 'name': 'hackrf', - 'data': hackrf_image, - 'size': 0x10000, - }, { 'name': 'baseband', 'data': baseband_image, - 'size': 0x20000, + 'size': 0x30000, }, { 'name': 'application', From eac4cf678a489f75b64e320eb6ff22b452c9a487 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 27 Feb 2016 12:10:39 -0800 Subject: [PATCH 110/165] Capture M4 chDbgPanic msg, show in application. --- firmware/application/event_m0.cpp | 37 +++++++++++++++++++++ firmware/application/event_m0.hpp | 1 + firmware/common/debug.cpp | 12 +++++++ firmware/common/portapack_shared_memory.hpp | 2 ++ 4 files changed, 52 insertions(+) diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 96df09a4..3acdb4f6 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -40,6 +40,8 @@ using namespace lpc43xx; #include +#include "ui_font_fixed_8x16.hpp" + extern "C" { CH_IRQ_HANDLER(M4Core_IRQHandler) { @@ -133,6 +135,40 @@ eventmask_t EventDispatcher::wait() { } void EventDispatcher::dispatch(const eventmask_t events) { + if( shared_memory.m4_panic_msg[0] != 0 ) { + halt = true; + } + + if( halt ) { + if( shared_memory.m4_panic_msg[0] != 0 ) { + painter.fill_rectangle( + { 0, 0, portapack::display.width(), portapack::display.height() }, + ui::Color::red() + ); + + constexpr int border = 8; + painter.fill_rectangle( + { border, border, portapack::display.width() - (border * 2), portapack::display.height() - (border * 2) }, + ui::Color::black() + ); + + painter.draw_string({ 48, 24 }, top_widget->style(), "M4 Guru Meditation"); + + shared_memory.m4_panic_msg[sizeof(shared_memory.m4_panic_msg) - 1] = 0; + const std::string message = shared_memory.m4_panic_msg; + const int x_offset = (portapack::display.width() - (message.size() * 8)) / 2; + constexpr int y_offset = (portapack::display.height() - 16) / 2; + painter.draw_string( + { x_offset, y_offset }, + top_widget->style(), + message + ); + + shared_memory.m4_panic_msg[0] = 0; + } + return; + } + if( events & EVT_MASK_APPLICATION ) { handle_application_queue(); } @@ -291,6 +327,7 @@ void EventDispatcher::init_message_queues() { new (&shared_memory.app_local_queue) MessageQueue( shared_memory.app_local_queue_data, SharedMemory::app_local_queue_k ); + shared_memory.m4_panic_msg[0] = 0; } MessageHandlerRegistration::MessageHandlerRegistration( diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 35de0e4d..d08ce78a 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -102,6 +102,7 @@ private: bool is_running = true; bool sd_card_present = false; bool display_sleep = false; + bool halt = false; eventmask_t wait(); void dispatch(const eventmask_t events); diff --git a/firmware/common/debug.cpp b/firmware/common/debug.cpp index 886abeaf..218bf236 100644 --- a/firmware/common/debug.cpp +++ b/firmware/common/debug.cpp @@ -24,6 +24,8 @@ #include #include +#include "portapack_shared_memory.hpp" + #if defined(LPC43XX_M0) static void debug_indicate_error_init() { // TODO: Get knowledge of LED GPIO port/bit from shared place. @@ -75,6 +77,16 @@ void __early_init(void) { } void port_halt(void) { + // Copy debug panic message to M0 region. + const auto* p = dbg_panic_msg; + for(size_t i=0; i Date: Sat, 2 Jul 2016 16:02:03 -0700 Subject: [PATCH 111/165] Clear baseband message for non-shutdown messages. --- firmware/baseband/event_m4.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/baseband/event_m4.cpp b/firmware/baseband/event_m4.cpp index 49c98caf..c1b395b2 100644 --- a/firmware/baseband/event_m4.cpp +++ b/firmware/baseband/event_m4.cpp @@ -92,7 +92,6 @@ void EventDispatcher::handle_baseband_queue() { const auto message = shared_memory.baseband_message; if( message ) { on_message(message); - shared_memory.baseband_message = nullptr; } } @@ -104,6 +103,7 @@ void EventDispatcher::on_message(const Message* const message) { default: on_message_default(message); + shared_memory.baseband_message = nullptr; break; } } From b2d5e473083a4973a20c7a18b1ad0237ee00d9ed Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Jul 2016 16:02:50 -0700 Subject: [PATCH 112/165] Clear baseband message at end of shutdown(). Allow baseband to shut down completely before shutdown message is acknowledged. --- firmware/baseband/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index 2fa72999..e99a0f34 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -100,6 +100,8 @@ static void shutdown() { ShutdownMessage shutdown_message; shared_memory.application_queue.push(shutdown_message); + shared_memory.baseband_message = nullptr; + halt(); } From 34e45412d157abe91a333c6652a04cdd0c403761 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Jul 2016 16:12:36 -0700 Subject: [PATCH 113/165] Dumb baseband-running state tracking to ease use of baseband API. --- firmware/application/analog_audio_app.cpp | 2 ++ firmware/application/baseband_api.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index fa2ba2e4..872a57c2 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -271,6 +271,8 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) { audio::output::mute(); record_view.stop(); + baseband::shutdown(); + portapack::spi_flash::image_tag_t image_tag; switch(modulation) { case ReceiverModel::Mode::AMAudio: image_tag = portapack::spi_flash::image_tag_am_audio; break; diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 599a31b8..0e50c5c1 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -90,17 +90,30 @@ void stop() { send_message(&message); } +static bool baseband_image_running = false; + void run_image(const portapack::spi_flash::image_tag_t image_tag) { + if( baseband_image_running ) { + chDbgPanic("BBRunning"); + } + m4_init(image_tag, portapack::memory::map::m4_code); + baseband_image_running = true; creg::m4txevent::enable(); } void shutdown() { + if( !baseband_image_running ) { + return; + } + creg::m4txevent::disable(); ShutdownMessage message; send_message(&message); + + baseband_image_running = false; } void spectrum_streaming_start() { From 30efa53956da053919c2e5b9a3c96ae00ba6208d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Jul 2016 16:15:43 -0700 Subject: [PATCH 114/165] Clear M4->M0 interrupt before M4 image is loaded. ...out of an abundance of caution. --- firmware/application/baseband_api.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 0e50c5c1..10f5a92a 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -97,6 +97,8 @@ void run_image(const portapack::spi_flash::image_tag_t image_tag) { chDbgPanic("BBRunning"); } + creg::m4txevent::clear(); + m4_init(image_tag, portapack::memory::map::m4_code); baseband_image_running = true; From 57293bc5eb55f4a22606326e0dea5a6c7dfd6450 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Jul 2016 16:19:28 -0700 Subject: [PATCH 115/165] Clear application message queue after baseband is shut down. --- firmware/application/baseband_api.cpp | 2 ++ firmware/common/message_queue.hpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 10f5a92a..a28be777 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -115,6 +115,8 @@ void shutdown() { ShutdownMessage message; send_message(&message); + shared_memory.application_queue.reset(); + baseband_image_running = false; } diff --git a/firmware/common/message_queue.hpp b/firmware/common/message_queue.hpp index 3e0a1cbb..84bbaa9c 100644 --- a/firmware/common/message_queue.hpp +++ b/firmware/common/message_queue.hpp @@ -74,6 +74,10 @@ public: return fifo.is_empty(); } + void reset() { + fifo.reset(); + } + private: FIFO fifo; Mutex mutex_write; From c52f5fa26c6068f74b9fc95aeb04cc9d429e8a3a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Jul 2016 16:38:01 -0700 Subject: [PATCH 116/165] Expose static EventDispatcher to stop main loop. Used to fix reboot into HackRF firmware. --- firmware/application/event_m0.cpp | 2 ++ firmware/application/event_m0.hpp | 4 ++-- firmware/application/ui_navigation.cpp | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 3acdb4f6..6f291dd3 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -90,6 +90,7 @@ private: static MessageHandlerMap message_map; Thread* EventDispatcher::thread_event_loop = nullptr; +bool EventDispatcher::is_running = false; EventDispatcher::EventDispatcher( ui::Widget* const top_widget, @@ -101,6 +102,7 @@ EventDispatcher::EventDispatcher( init_message_queues(); thread_event_loop = chThdSelf(); + is_running = true; touch_manager.on_event = [this](const ui::TouchEvent event) { this->on_touch_event(event); }; diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index d08ce78a..f89f0b75 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -50,7 +50,7 @@ public: ); void run(); - void request_stop(); + static void request_stop(); void set_display_sleep(const bool sleep); @@ -99,7 +99,7 @@ private: ui::Painter painter; ui::Context& context; uint32_t encoder_last = 0; - bool is_running = true; + static bool is_running; bool sd_card_present = false; bool display_sleep = false; bool halt = false; diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 20110b68..4238af12 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -251,8 +251,8 @@ Context& SystemView::context() const { /* HackRFFirmwareView ****************************************************/ HackRFFirmwareView::HackRFFirmwareView(NavigationView& nav) { - button_yes.on_select = [&nav](Button&){ - m4_request_shutdown(); + button_yes.on_select = [](Button&){ + EventDispatcher::request_stop(); }; button_no.on_select = [&nav](Button&){ From dacb94a1897d4dbc5d7e563a32dc72aa7a07d9dc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Jul 2016 17:36:48 -0700 Subject: [PATCH 117/165] Ask Travis-CI to update CMake version during builds. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b3c875dd..f842e8ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ addons: - lib32bz2-1.0 - lib32ncurses5 - lib32z1 + - cmake artifacts: paths: - $(ls build/firmware/portapack-h1-firmware-*.tar.bz2 | tr "\n" ":") From f10eb77436c8e426f6022e54e76828e0ae97fd69 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Jul 2016 17:46:51 -0700 Subject: [PATCH 118/165] Travis CMake update shot in the dark... --- .travis.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index f842e8ae..306d20f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,11 +29,14 @@ script: - popd addons: - apt_packages: - - lib32bz2-1.0 - - lib32ncurses5 - - lib32z1 - - cmake + apt: + packages: + - lib32bz2-1.0 + - lib32ncurses5 + - lib32z1 + - cmake + sources: + - kalakris-cmake artifacts: paths: - $(ls build/firmware/portapack-h1-firmware-*.tar.bz2 | tr "\n" ":") From 53434f37893e5374fd28ffab46b09658f2e15eff Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Jul 2016 18:15:39 -0700 Subject: [PATCH 119/165] Fix Python2 string type error. --- firmware/tools/make_image_chunk.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/tools/make_image_chunk.py b/firmware/tools/make_image_chunk.py index 53d9b14d..ed3463bc 100755 --- a/firmware/tools/make_image_chunk.py +++ b/firmware/tools/make_image_chunk.py @@ -43,11 +43,11 @@ def write_image(data, path): if len(sys.argv) == 4: input_image = read_image(sys.argv[1]) - tag = sys.argv[2].encode() + tag = tuple(map(ord, sys.argv[2])) output_path = sys.argv[3] elif len(sys.argv) == 2: input_image = bytearray() - tag = bytearray((0,) * 4) + tag = (0, 0, 0, 0) output_path = sys.argv[1] else: print(usage_message) @@ -64,7 +64,7 @@ if (len(input_image) & 3) != 0: raise RuntimeError('image size of %d is not multiple of four' % (len(input_image,))) output_image = bytearray() -output_image += struct.pack('<4sI', tag, len(input_image)) +output_image += struct.pack('<4BI', tag[0], tag[1], tag[2], tag[3], len(input_image)) output_image += input_image write_image(output_image, output_path) From 45ca3cf7e698cc3a93b192e651b429bd3406f94d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 3 Jul 2016 11:32:21 -0700 Subject: [PATCH 120/165] CMake: reduce intermediate targets, add script dependencies. --- firmware/application/CMakeLists.txt | 4 ++-- firmware/baseband/CMakeLists.txt | 26 ++++++++++++++------------ firmware/bootstrap/CMakeLists.txt | 4 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 27a3e33d..f9995934 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -300,8 +300,8 @@ include_directories(. ${INCDIR}) link_directories(${LLIBDIR}) target_link_libraries(${PROJECT_NAME}.elf ${LIBS}) -add_custom_target( - ${PROJECT_NAME}.bin +add_custom_command( + OUTPUT ${PROJECT_NAME}.bin COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin DEPENDS ${PROJECT_NAME}.elf ) diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 717d7b5b..dfc7d686 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -259,16 +259,16 @@ macro(DeclareTargets chunk_tag name) link_directories(${LLIBDIR}) target_link_libraries(${PROJECT_NAME}.elf ${LIBS}) - add_custom_target( - ${PROJECT_NAME}.bin + add_custom_command( + OUTPUT ${PROJECT_NAME}.bin COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin DEPENDS ${PROJECT_NAME}.elf ) - add_custom_target( - ${PROJECT_NAME}.img + add_custom_command( + OUTPUT ${PROJECT_NAME}.img COMMAND ${MAKE_IMAGE_CHUNK} ${PROJECT_NAME}.bin ${chunk_tag} ${PROJECT_NAME}.img - DEPENDS ${PROJECT_NAME}.bin + DEPENDS ${PROJECT_NAME}.bin ${MAKE_IMAGE_CHUNK} ) set(BASEBAND_IMAGES ${BASEBAND_IMAGES} ${PROJECT_NAME}.img) @@ -332,24 +332,26 @@ DeclareTargets(PSPE wideband_spectrum) ### HackRF "factory" firmware -add_custom_target( - hackrf.bin +add_custom_command( + OUTPUT hackrf.bin COMMAND ${STRIP_DFU} ${HACKRF_FIRMWARE_IMAGE} hackrf.bin + DEPENDS ${HACKRF_FIRMWARE_IMAGE} ${STRIP_DFU} ) -add_custom_target( - hackrf.img +add_custom_command( + OUTPUT hackrf.img COMMAND ${MAKE_IMAGE_CHUNK} hackrf.bin HRF1 hackrf.img - DEPENDS hackrf.bin + DEPENDS hackrf.bin ${MAKE_IMAGE_CHUNK} ) set(BASEBAND_IMAGES ${BASEBAND_IMAGES} hackrf.img) ### Terminator image -add_custom_target( - terminator.img +add_custom_command( + OUTPUT terminator.img COMMAND ${MAKE_IMAGE_CHUNK} terminator.img + DEPENDS ${MAKE_IMAGE_CHUNK} ) ####################################################################### diff --git a/firmware/bootstrap/CMakeLists.txt b/firmware/bootstrap/CMakeLists.txt index 27c1271d..07c8abe1 100644 --- a/firmware/bootstrap/CMakeLists.txt +++ b/firmware/bootstrap/CMakeLists.txt @@ -199,8 +199,8 @@ include_directories(. ${INCDIR}) link_directories(${LLIBDIR}) target_link_libraries(${PROJECT_NAME}.elf ${LIBS}) -add_custom_target( - ${PROJECT_NAME}.bin +add_custom_command( + OUTPUT ${PROJECT_NAME}.bin COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin DEPENDS ${PROJECT_NAME}.elf ) From b6fe39251214b7314a6bd617b764ca0e425c470b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 3 Jul 2016 18:32:50 -0700 Subject: [PATCH 121/165] CMake: Improve dependencies, how output files are managed/cleaned. I almost think I understand CMake, now. Almost. --- firmware/CMakeLists.txt | 39 +++++++++++++++++++-------- firmware/application/CMakeLists.txt | 5 ++++ firmware/baseband/CMakeLists.txt | 41 ++++++++++++++++------------- firmware/bootstrap/CMakeLists.txt | 5 ++++ 4 files changed, 60 insertions(+), 30 deletions(-) diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 68c1e2e2..b902226a 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -18,7 +18,7 @@ # Boston, MA 02110-1301, USA. # -project(portapack-h1-firmware) +project(firmware) set(COMMON ${PROJECT_SOURCE_DIR}/common) set(CHIBIOS ${PROJECT_SOURCE_DIR}/chibios) @@ -30,31 +30,48 @@ set(STRIP_DFU ${PROJECT_SOURCE_DIR}/tools/strip_dfu.py) set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py) set(MAKE_IMAGE_CHUNK ${PROJECT_SOURCE_DIR}/tools/make_image_chunk.py) +set(FIRMWARE_NAME portapack-h1-firmware) +set(FIRMWARE_FILENAME ${FIRMWARE_NAME}.bin) + add_subdirectory(application) add_subdirectory(baseband) add_subdirectory(bootstrap) +# NOTE: Dependencies break if the .bin files aren't included in DEPENDS. WTF, CMake? +add_custom_command( + OUTPUT ${FIRMWARE_FILENAME} + COMMAND ${MAKE_SPI_IMAGE} ${bootstrap_BINARY_DIR}/bootstrap.bin ${baseband_BINARY_DIR}/baseband.img ${application_BINARY_DIR}/application.bin ${FIRMWARE_FILENAME} + DEPENDS bootstrap baseband application ${MAKE_SPI_IMAGE} + ${bootstrap_BINARY_DIR}/bootstrap.bin ${baseband_BINARY_DIR}/baseband.img ${application_BINARY_DIR}/application.bin + VERBATIM +) + add_custom_target( - ${PROJECT_NAME}.bin - COMMAND ${MAKE_SPI_IMAGE} ${bootstrap_BINARY_DIR}/bootstrap.bin ${baseband_BINARY_DIR}/baseband.img ${application_BINARY_DIR}/application.bin ${PROJECT_NAME}.bin - DEPENDS bootstrap.bin baseband.img application.bin + firmware + DEPENDS ${FIRMWARE_FILENAME} ) add_custom_target( program COMMAND dfu-util --device 1fc9:000c --download ${HACKRF_FIRMWARE_IMAGE} --reset COMMAND sleep 1s - COMMAND hackrf_spiflash -w ${PROJECT_NAME}.bin - DEPENDS ${PROJECT_NAME}.bin + COMMAND hackrf_spiflash -w ${FIRMWARE_FILENAME} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${FIRMWARE_FILENAME} ) # TODO: Bad hack to fix location of LICENSE file for tar. -add_custom_target( - release +add_custom_command( + OUTPUT ${FIRMWARE_NAME}-${GIT_REVISION}.tar.bz2 ${FIRMWARE_NAME}-${GIT_REVISION}.zip COMMAND cp ${LICENSE_PATH} LICENSE COMMAND cp ${HACKRF_FIRMWARE_IMAGE} ${HACKRF_FIRMWARE_FILENAME} - COMMAND tar -c -j -f ${PROJECT_NAME}-${GIT_REVISION}.tar.bz2 ${PROJECT_NAME}.bin ${HACKRF_FIRMWARE_FILENAME} LICENSE - COMMAND zip -9 -q ${PROJECT_NAME}-${GIT_REVISION}.zip ${PROJECT_NAME}.bin ${HACKRF_FIRMWARE_FILENAME} LICENSE + COMMAND tar -c -j -f ${FIRMWARE_NAME}-${GIT_REVISION}.tar.bz2 ${FIRMWARE_FILENAME} ${HACKRF_FIRMWARE_FILENAME} LICENSE + COMMAND zip -9 -q ${FIRMWARE_NAME}-${GIT_REVISION}.zip ${FIRMWARE_FILENAME} ${HACKRF_FIRMWARE_FILENAME} LICENSE COMMAND rm -f LICENSE ${HACKRF_FIRMWARE_FILENAME} - DEPENDS ${PROJECT_NAME}.bin + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${FIRMWARE_FILENAME} ${LICENSE_PATH} ${HACKRF_FIRMWARE_IMAGE} + VERBATIM +) + +add_custom_target( + release + DEPENDS ${FIRMWARE_NAME}-${GIT_REVISION}.tar.bz2 ${FIRMWARE_NAME}-${GIT_REVISION}.zip ) diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index f9995934..d0719340 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -305,3 +305,8 @@ add_custom_command( COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin DEPENDS ${PROJECT_NAME}.elf ) + +add_custom_target( + ${PROJECT_NAME} + DEPENDS ${PROJECT_NAME}.bin +) diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index dfc7d686..6d30a8ec 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -26,7 +26,7 @@ enable_language(C CXX ASM) -project(baseband) +project(baseband_shared) # Compiler options here. set(USE_OPT "-O3 -falign-functions=16 -fno-math-errno --specs=nano.specs") @@ -253,22 +253,18 @@ macro(DeclareTargets chunk_tag name) project("baseband_${name}") include(${RULESPATH}/rules.cmake) - add_executable(${PROJECT_NAME}.elf $ ${MODE_CPPSRC} ${LDSCRIPT}) + add_executable(${PROJECT_NAME}.elf $ ${MODE_CPPSRC} ${LDSCRIPT}) add_definitions(${DEFS}) include_directories(. ${INCDIR}) link_directories(${LLIBDIR}) target_link_libraries(${PROJECT_NAME}.elf ${LIBS}) add_custom_command( - OUTPUT ${PROJECT_NAME}.bin + OUTPUT ${PROJECT_NAME}.bin ${PROJECT_NAME}.img COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin - DEPENDS ${PROJECT_NAME}.elf - ) - - add_custom_command( - OUTPUT ${PROJECT_NAME}.img COMMAND ${MAKE_IMAGE_CHUNK} ${PROJECT_NAME}.bin ${chunk_tag} ${PROJECT_NAME}.img - DEPENDS ${PROJECT_NAME}.bin ${MAKE_IMAGE_CHUNK} + DEPENDS ${PROJECT_NAME}.elf ${MAKE_IMAGE_CHUNK} + VERBATIM ) set(BASEBAND_IMAGES ${BASEBAND_IMAGES} ${PROJECT_NAME}.img) @@ -333,15 +329,11 @@ DeclareTargets(PSPE wideband_spectrum) ### HackRF "factory" firmware add_custom_command( - OUTPUT hackrf.bin + OUTPUT hackrf.bin hackrf.img COMMAND ${STRIP_DFU} ${HACKRF_FIRMWARE_IMAGE} hackrf.bin - DEPENDS ${HACKRF_FIRMWARE_IMAGE} ${STRIP_DFU} -) - -add_custom_command( - OUTPUT hackrf.img COMMAND ${MAKE_IMAGE_CHUNK} hackrf.bin HRF1 hackrf.img - DEPENDS hackrf.bin ${MAKE_IMAGE_CHUNK} + DEPENDS ${HACKRF_FIRMWARE_IMAGE} ${STRIP_DFU} ${MAKE_IMAGE_CHUNK} + VERBATIM ) set(BASEBAND_IMAGES ${BASEBAND_IMAGES} hackrf.img) @@ -352,12 +344,23 @@ add_custom_command( OUTPUT terminator.img COMMAND ${MAKE_IMAGE_CHUNK} terminator.img DEPENDS ${MAKE_IMAGE_CHUNK} + VERBATIM ) +set(BASEBAND_IMAGES ${BASEBAND_IMAGES} terminator.img) + ####################################################################### +project(baseband) + +add_custom_command( + OUTPUT ${PROJECT_NAME}.img + COMMAND cat ${BASEBAND_IMAGES} > ${PROJECT_NAME}.img + DEPENDS ${BASEBAND_IMAGES} + VERBATIM +) + add_custom_target( - baseband.img - COMMAND cat ${BASEBAND_IMAGES} terminator.img >baseband.img - DEPENDS ${BASEBAND_IMAGES} terminator.img + ${PROJECT_NAME} + DEPENDS ${PROJECT_NAME}.img ) diff --git a/firmware/bootstrap/CMakeLists.txt b/firmware/bootstrap/CMakeLists.txt index 07c8abe1..35af3025 100644 --- a/firmware/bootstrap/CMakeLists.txt +++ b/firmware/bootstrap/CMakeLists.txt @@ -204,3 +204,8 @@ add_custom_command( COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin DEPENDS ${PROJECT_NAME}.elf ) + +add_custom_target( + bootstrap + DEPENDS ${PROJECT_NAME}.bin +) From 0899c48735ea67e034a4a400762e702c6e9f9038 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 3 Jul 2016 18:33:36 -0700 Subject: [PATCH 122/165] Remove linker map generation, other unnecessary(?) flags. --- firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake b/firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake index fef8f450..2e20d853 100644 --- a/firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake +++ b/firmware/chibios/os/ports/GCC/ARMCMx/rules.cmake @@ -69,7 +69,7 @@ set(ASFLAGS "${MCFLAGS} ${ADEFS}") set(ASXFLAGS "${MCFLAGS} ${ADEFS}") set(CFLAGS "${MCFLAGS} ${OPT} ${COPT} ${CWARN}") set(CPPFLAGS "${MCFLAGS} ${OPT} ${CPPOPT} ${CPPWARN}") -set(LDFLAGS "-nostartfiles -Wl,-Map=${PROJECT_NAME}.map,--cref,--no-warn-mismatch,--library-path=${RULESPATH},--script=${LDSCRIPT}${LDOPT}") +set(LDFLAGS "-nostartfiles -Wl,--library-path=${RULESPATH},--script=${LDSCRIPT}${LDOPT}") # Thumb interwork enabled only if needed because it kills performance. if(DEFINED TSRC) From 42190b958742bfa0f5877fc9376f04f429350a1b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 3 Jul 2016 18:48:39 -0700 Subject: [PATCH 123/165] CMake: Fix ldscript dependencies. --- firmware/application/CMakeLists.txt | 3 ++- firmware/baseband/CMakeLists.txt | 3 ++- firmware/bootstrap/CMakeLists.txt | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index d0719340..76f7dc7c 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -294,7 +294,8 @@ include(${RULESPATH}/rules.cmake) ############################################################################## -add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC} ${LDSCRIPT}) +add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC}) +set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_DEPENDS ${LDSCRIPT}) add_definitions(${DEFS}) include_directories(. ${INCDIR}) link_directories(${LLIBDIR}) diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 6d30a8ec..2aaa3028 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -253,7 +253,8 @@ macro(DeclareTargets chunk_tag name) project("baseband_${name}") include(${RULESPATH}/rules.cmake) - add_executable(${PROJECT_NAME}.elf $ ${MODE_CPPSRC} ${LDSCRIPT}) + add_executable(${PROJECT_NAME}.elf $ ${MODE_CPPSRC}) + set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_DEPENDS ${LDSCRIPT}) add_definitions(${DEFS}) include_directories(. ${INCDIR}) link_directories(${LLIBDIR}) diff --git a/firmware/bootstrap/CMakeLists.txt b/firmware/bootstrap/CMakeLists.txt index 35af3025..4c4d5a41 100644 --- a/firmware/bootstrap/CMakeLists.txt +++ b/firmware/bootstrap/CMakeLists.txt @@ -193,7 +193,8 @@ include(${RULESPATH}/rules.cmake) ############################################################################## -add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC} ${LDSCRIPT}) +add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC}) +set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_DEPENDS ${LDSCRIPT}) add_definitions(${DEFS}) include_directories(. ${INCDIR}) link_directories(${LLIBDIR}) From db700b1beb024be3aeda28cc73c9262891c95420 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 5 Jul 2016 09:58:38 -0700 Subject: [PATCH 124/165] Travis: Update to latest Launchpad ARM GCC release. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 306d20f5..64dd7d69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,9 +14,9 @@ notifications: - "Firmware download : https://portapack-h1-builds.s3.amazonaws.com/%{repository_slug}/%{build_number}/%{build_number}.1/firmware/portapack-h1-firmware-%{commit}.tar.bz2" before_script: - - wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q1-update/+download/gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2 -O /tmp/gcc-arm.tar.bz2 + - wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2 -O /tmp/gcc-arm.tar.bz2 - tar -xf /tmp/gcc-arm.tar.bz2 - - export PATH=$PWD/gcc-arm-none-eabi-5_3-2016q1/bin:$PATH + - export PATH=$PWD/gcc-arm-none-eabi-5_4-2016q2/bin:$PATH - export CC="arm-none-eabi-gcc" - export CXX="arm-none-eabi-g++" From df825807d69f64c02a25274e0ca6a788c7ba3979 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 5 Jul 2016 11:57:57 -0700 Subject: [PATCH 125/165] CRC: Rearrange public methods to reduce user error. If you can access process_bits() without considering RevIn value, you will likely not get the CRC value you're expecting! Put RevIn check where it belongs, in process_bits(). --- firmware/common/crc.hpp | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/firmware/common/crc.hpp b/firmware/common/crc.hpp index cc56597c..fab78a6b 100644 --- a/firmware/common/crc.hpp +++ b/firmware/common/crc.hpp @@ -78,27 +78,15 @@ public: } void process_bits(value_type bits, size_t bit_count) { - constexpr auto digits = std::numeric_limits::digits; - constexpr auto mask = static_cast(1) << (digits - 1); - - bits <<= (std::numeric_limits::digits - bit_count); - for(size_t i=bit_count; i>0; --i, bits <<= 1) { - process_bit(static_cast(bits & mask)); - } - } - - void process_bits_lsb_first(value_type bits, size_t bit_count) { - for(size_t i=bit_count; i>0; --i, bits >>= 1) { - process_bit(static_cast(bits & 0x01)); + if( RevIn ) { + process_bits_lsb_first(bits, bit_count); + } else { + process_bits_msb_first(bits, bit_count); } } void process_byte(const uint8_t byte) { - if( RevIn ) { - process_bits_lsb_first(byte, 8); - } else { - process_bits(byte, 8); - } + process_bits(byte, 8); } void process_bytes(const void* const data, const size_t length) { @@ -147,6 +135,22 @@ private: } return reflection; } + + void process_bits_msb_first(value_type bits, size_t bit_count) { + constexpr auto digits = std::numeric_limits::digits; + constexpr auto mask = static_cast(1) << (digits - 1); + + bits <<= (std::numeric_limits::digits - bit_count); + for(size_t i=bit_count; i>0; --i, bits <<= 1) { + process_bit(static_cast(bits & mask)); + } + } + + void process_bits_lsb_first(value_type bits, size_t bit_count) { + for(size_t i=bit_count; i>0; --i, bits >>= 1) { + process_bit(static_cast(bits & 0x01)); + } + } }; class Adler32 { From 3ed1d9e24a7784bd9857fc84b3f5e69f493a7c5a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 5 Jul 2016 12:06:51 -0700 Subject: [PATCH 126/165] CPLD: Method to calculate bitstream CRC32. --- firmware/common/cpld_max5.cpp | 18 ++++++++++++++++++ firmware/common/cpld_max5.hpp | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/firmware/common/cpld_max5.cpp b/firmware/common/cpld_max5.cpp index b6c4f6c5..f0c13d68 100644 --- a/firmware/common/cpld_max5.cpp +++ b/firmware/common/cpld_max5.cpp @@ -114,6 +114,13 @@ bool CPLD::verify( return block_0_success && block_1_success; } +uint32_t CPLD::crc() { + crc_t crc { 0x04c11db7, 0xffffffff, 0xffffffff }; + block_crc(0, 3328, crc); + block_crc(1, 512, crc); + return crc.checksum(); +} + void CPLD::sector_select(const uint16_t id) { shift_ir(0x203); // Sector select jtag.runtest_tck(93); // 5us @@ -219,6 +226,17 @@ bool CPLD::is_blank_block(const uint16_t id, const size_t count) { return success; } +void CPLD::block_crc(const uint16_t id, const size_t count, crc_t& crc) { + sector_select(id); + shift_ir(0x205); // Read + jtag.runtest_tck(93); // 5us + + for(size_t i=0; i #include @@ -75,6 +76,8 @@ public: bool is_blank(); + uint32_t crc(); + std::pair boundary_scan(); enum class Instruction { @@ -135,6 +138,9 @@ private: bool is_blank_block(const uint16_t id, const size_t count); + using crc_t = CRC<32, true, true>; + void block_crc(const uint16_t id, const size_t count, crc_t& crc); + const uint32_t IDCODE = 0b00000010000010100101000011011101; const size_t IR_LENGTH = 10; From 740edc4d49f6645a6ff06adc00771e31b2ae1c18 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 5 Jul 2016 12:08:56 -0700 Subject: [PATCH 127/165] Remove PortaPack CPLD checksum display. No point in calculating or showing, since full compare against desired bits is done at every startup -- way better than a CRC, and if it fails tries to program. If programming fails, the PortaPack panics and LED flashes. --- firmware/application/ui_setup.cpp | 1 - firmware/application/ui_setup.hpp | 5 ----- 2 files changed, 6 deletions(-) diff --git a/firmware/application/ui_setup.cpp b/firmware/application/ui_setup.cpp index 95beba9b..da662404 100644 --- a/firmware/application/ui_setup.cpp +++ b/firmware/application/ui_setup.cpp @@ -172,7 +172,6 @@ AboutView::AboutView(NavigationView& nav) { &text_title, &text_firmware, &text_cpld_hackrf, - &text_cpld_portapack, &button_ok, } }); diff --git a/firmware/application/ui_setup.hpp b/firmware/application/ui_setup.hpp index 8442c711..016d11ab 100644 --- a/firmware/application/ui_setup.hpp +++ b/firmware/application/ui_setup.hpp @@ -239,11 +239,6 @@ private: "HackRF CPLD CRC 0x????????", }; - Text text_cpld_portapack { - { 0, 160, 240, 16 }, - "PortaPack CPLD CRC 0x????????", - }; - Button button_ok { { 72, 192, 96, 24 }, "OK" From 7bcde5405026a3b6e38178c44d1fb1b0c7e56457 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 5 Jul 2016 12:33:15 -0700 Subject: [PATCH 128/165] Tool for generating CPLD bitstreams in C++ arrays, from SVF file. --- firmware/tools/extract_cpld_data.py | 124 ++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100755 firmware/tools/extract_cpld_data.py diff --git a/firmware/tools/extract_cpld_data.py b/firmware/tools/extract_cpld_data.py new file mode 100755 index 00000000..c4405854 --- /dev/null +++ b/firmware/tools/extract_cpld_data.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python + +# +# Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. +# + +# Very fragile code to extract data from Altera MAX V CPLD SVF + +import sys + +if len(sys.argv) != 2: + print('Usage: ') + sys.exit(-1) + +f = open(sys.argv[1], 'r') + +calculate_crc = False + +# !PROGRAM +# SIR 10 TDI (203); +# RUNTEST 93 TCK; +# SDR 13 TDI (0000); +# SIR 10 TDI (2F4); +# RUNTEST 93 TCK; +# while: + # SDR 16 TDI (7FFF); + # RUNTEST 1800 TCK; +# SIR 10 TDI (203); +# RUNTEST 93 TCK; +# SDR 13 TDI (0001); +# SIR 10 TDI (2F4); +# RUNTEST 93 TCK; + +phase = None + +block_0 = [] +block_1 = [] +current_block = None + +for line in f: + line = line.strip().upper() + + if line == '!PROGRAM': + phase = 'block_0' + current_block = block_0 + elif line == '!VERIFY': + phase = 'verify' + current_block = None + + if phase == 'block_0': + if line == 'SDR 13 TDI (0001);': + phase = 'block_1' + current_block = block_1 + + if phase == 'block_0' or phase == 'block_1': + if line.startswith('SDR 16 TDI ('): + sdr_value = int(line.split('(', 1)[1][:4], 16) + #print('0x%04x,' % sdr_value) + current_block.append(sdr_value) + +def print_block(block): + for n in range(0, len(block), 8): + chunk = block[n:n+8] + line = ['0x%04x,' % v for v in chunk] + print('\t%s' % ' '.join(line)) + +def crc32(blocks): + import zlib + + crc_bytes = [] + for block in blocks: + for word in block: + crc_bytes.append((word >> 0) & 0xff) + crc_bytes.append((word >> 8) & 0xff) + return zlib.crc32(bytearray(crc_bytes)) & 0xffffffff + +print("""#include "portapack_cpld_data.hpp" + +#include +#include + +namespace portapack { +namespace cpld { +""") + +print('const std::array block_0 { {' % len(block_0)) +print_block(block_0) + +print("""} }; +""") + +print('const std::array block_1 { {' % len(block_1)) +print_block(block_1) + +print("""} }; + +} /* namespace cpld */ +} /* namespace portapack */ +""") + +if calculate_crc: + # Apply post-programming modification to make post-programming CRC correct: + programmed_block_0 = block_0[:] + programmed_block_0[0] &= 0xfbff + + crc = crc32((programmed_block_0, block_1)) + print('%08x' % crc) From ad4a68f90a7c1025d251631efca12aba6be4fe7e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 5 Jul 2016 12:34:38 -0700 Subject: [PATCH 129/165] CMake: Generate portapack_cpld_data.cpp from SVF via tool. --- CMakeLists.txt | 1 + firmware/CMakeLists.txt | 1 + firmware/application/CMakeLists.txt | 11 +- firmware/common/portapack_cpld_data.cpp | 519 ------------------------ 4 files changed, 12 insertions(+), 520 deletions(-) delete mode 100644 firmware/common/portapack_cpld_data.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8750e289..371e26d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,5 +38,6 @@ else (GIT_REVISION_FOUND) endif (GIT_REVISION_FOUND) set(LICENSE_PATH ${CMAKE_CURRENT_LIST_DIR}/LICENSE) +set(HARDWARE_PATH ${CMAKE_CURRENT_LIST_DIR}/hardware) add_subdirectory(firmware) diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index b902226a..d63a3b54 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -26,6 +26,7 @@ set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu) set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME}) +set(EXTRACT_CPLD_DATA ${PROJECT_SOURCE_DIR}/tools/extract_cpld_data.py) set(STRIP_DFU ${PROJECT_SOURCE_DIR}/tools/strip_dfu.py) set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py) set(MAKE_IMAGE_CHUNK ${PROJECT_SOURCE_DIR}/tools/make_image_chunk.py) diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 76f7dc7c..46de19ba 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -71,6 +71,9 @@ set(USE_FPU no) # Project, sources and paths # +set(CPLD_SVF_PATH ${HARDWARE_PATH}/portapack_h1/cpld/output_files/portapack_h1_cpld.svf) +set(CPLD_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/portapack_cpld_data.cpp) + # Imported source files and paths include(${CHIBIOS_PORTAPACK}/boards/GSG_HACKRF_ONE/board.cmake) include(${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M0/platform.cmake) @@ -180,7 +183,7 @@ set(CPPSRC ${COMMON}/cpld_max5.cpp ${COMMON}/jtag.cpp cpld_update.cpp - ${COMMON}/portapack_cpld_data.cpp + ${CPLD_DATA_CPP} ) # C sources to be compiled in ARM mode regardless of the global setting. @@ -294,6 +297,12 @@ include(${RULESPATH}/rules.cmake) ############################################################################## +add_custom_command( + OUTPUT ${CPLD_DATA_CPP} + COMMAND ${EXTRACT_CPLD_DATA} ${CPLD_SVF_PATH} >${CPLD_DATA_CPP} + DEPENDS ${EXTRACT_CPLD_DATA} ${CPLD_SVF_PATH} +) + add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC}) set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_DEPENDS ${LDSCRIPT}) add_definitions(${DEFS}) diff --git a/firmware/common/portapack_cpld_data.cpp b/firmware/common/portapack_cpld_data.cpp deleted file mode 100644 index 08697da0..00000000 --- a/firmware/common/portapack_cpld_data.cpp +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. - */ - -#include "portapack_cpld_data.hpp" - -#include -#include - -namespace portapack { -namespace cpld { - -/* 2015 Aug 21 12:12 PT */ - -const std::array block_0 { { - 0x7fff, 0xffff, 0xbffc, 0xf9e7, 0x79ff, 0xfffe, 0xaf9e, 0x7cff, - 0x7fff, 0xfbe7, 0xb3f7, 0xffff, 0x7f3f, 0x7dfb, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbff7, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x67ff, 0xffff, 0xbfff, 0xfefd, 0x7fff, 0xff7f, 0xbfff, 0xe7f9, - 0x723f, 0xfff9, 0xb77f, 0xcccf, 0x7fff, 0xb99f, 0xbccc, 0xcffe, - 0x6fff, 0xffff, 0xbfff, 0xffeb, 0x77f3, 0xffff, 0xbfe6, 0xffff, - 0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xfbfe, - 0x7fff, 0xffff, 0xbfff, 0xfffe, 0x6fff, 0xffff, 0xbfef, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe, - 0x6fff, 0xffff, 0xbfff, 0xffdb, 0x7fff, 0xffff, 0xbff7, 0xffff, - 0x7dff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff5, 0xffff, 0xbffd, 0xffff, - 0x7eff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x6fff, 0xffff, 0xbfff, 0xfdbb, 0x77ef, 0xbfff, 0xbfff, 0xf7ff, - 0x7eef, 0xefff, 0xbfff, 0xffff, 0x7dff, 0xffff, 0xbfff, 0xffff, - 0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbffd, 0xffff, - 0x7dff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xff7f, 0x77ff, 0xffff, 0xbfff, 0xf7ff, - 0x7dff, 0xefff, 0xbfff, 0xffff, 0x7dff, 0xffff, 0xbfff, 0xfffe, - 0x7fff, 0xffff, 0xbfff, 0xfef7, 0x7ff7, 0xbfff, 0xbffd, 0xffff, - 0x7ef7, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe, - 0x6fff, 0xffff, 0xbffe, 0xffdf, 0x7fff, 0xffbf, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xb7ff, 0xffff, 0x7eff, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfeff, - 0x7fff, 0xffff, 0xb5fd, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xadff, 0xffbf, 0x7ffe, 0xffff, 0xbfef, 0xff5f, - 0x7fff, 0xffff, 0xbfff, 0xffef, 0x7fff, 0xffdf, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7dff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7ff7, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xf6ff, 0xbbcb, 0xffff, - 0x77ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7ff7, 0xffdf, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xfaff, 0xbfd5, 0xffff, - 0x77ff, 0xffff, 0xa55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fdf, 0xdeef, 0xbfff, 0xfdff, - 0x7fff, 0xffff, 0xafff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffd, 0xffff, 0xbffb, 0xffeb, - 0x6bff, 0xffff, 0xb55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbdff, 0xdff5, - 0x77ff, 0xffff, 0xbabf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffb, 0xf9bf, 0xbafe, 0xefff, - 0x6fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffe, 0xffde, 0xbfdf, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff7, 0xdfff, 0xbffd, 0x35ff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fd2, 0xffff, 0xbfbc, 0xc7ff, - 0x7fff, 0xffff, 0xb7af, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xddee, 0xb9ff, 0xbdff, - 0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffd, 0xea9f, 0xbefb, 0x7bff, - 0x7fff, 0xffff, 0xbeaf, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7ffd, 0x0ddf, 0xb598, 0x5e74, - 0x7fff, 0xffff, 0xb65f, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf, - 0x7fff, 0xffff, 0xbffe, 0xffff, 0x7ffc, 0x0ddd, 0xbd99, 0x1e6a, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7f08, 0x388f, 0xb89e, 0x887f, - 0x7bff, 0xffff, 0xb6f7, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7f0c, 0x388f, 0xb89f, 0x983b, - 0x67ff, 0xffff, 0xbfff, 0x3333, 0x63e6, 0x6667, 0xb333, 0x31f3, - 0x6666, 0x7ccc, 0xb98f, 0x9999, 0x73e8, 0xc445, 0xb938, 0x88ff, - 0x7fff, 0xffff, 0xb7ff, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab, - 0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bcd, 0xdcca, 0xb19d, 0xddfb, - 0x7bff, 0xffff, 0xbdf7, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xe66f, 0xb37f, 0xffde, - 0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7feb, 0xeedf, 0xbfdf, 0xfcff, - 0x7fff, 0xffff, 0xbfff, 0xeeee, 0x7ffb, 0xfbbf, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7dfd, 0xffff, 0xbffd, 0xdfff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffa, 0xefdf, 0xbfff, 0xdfff, - 0x7fff, 0xffff, 0xbbfe, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fef, 0xfeff, 0xbfdd, 0xfd7a, - 0x77ff, 0xffff, 0xbebe, 0xfff7, 0x7fff, 0xfb7f, 0xbf9f, 0xefff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfef, 0xfffb, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbaff, 0xfffd, - 0x7fff, 0xfdff, 0xbfff, 0xdfde, 0x7ffb, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xb7fd, 0xfff7, 0x7fff, 0xfdfb, 0xb7ff, 0xdfff, - 0x7fff, 0xedff, 0xbfff, 0xffff, 0x7ffe, 0xffff, 0xbff3, 0xbbf7, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xff7f, 0xbeaf, 0xfffe, - 0x7fff, 0xffff, 0xbfff, 0xbfbe, 0x7ffb, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbdee, 0xb7f7, 0x7fff, 0xfbef, 0xbfff, 0xffff, - 0x7fff, 0xfbfe, 0xbfff, 0xfedf, 0x6dff, 0xffff, 0xbfff, 0xffdf, - 0x7fff, 0xffff, 0xb7ff, 0xefdf, 0x7fef, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xfff7, 0xadbf, 0xffef, 0x7fff, 0xffff, 0xbfff, 0xfffb, - 0x7fff, 0xffff, 0xbffd, 0xdfff, 0x7ff7, 0xfdff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffd7, 0x6eff, 0xffff, 0xbfff, 0xffdf, - 0x7fff, 0xffff, 0xbadf, 0x7bd7, 0x7fff, 0xffef, 0xbfff, 0xffff, - 0x7fff, 0xfbf9, 0xb3ff, 0xfeff, 0x7fff, 0xffff, 0xbfff, 0xfffb, - 0x7fff, 0xffff, 0xbe5f, 0xff77, 0x7fff, 0xfefd, 0xbfff, 0xffff, - 0x7fff, 0xfeee, 0xbfbf, 0xfb3b, 0x77ff, 0xffff, 0xbfff, 0xffea, - 0x7fff, 0xffff, 0xbbff, 0xffff, 0x6fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xd7ff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7bff, 0xffff, 0xbbaf, 0xffff, 0x7ff7, 0x7fff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbbff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff4, - 0x7fff, 0xffff, 0xbdaf, 0x7bff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xf7ba, 0xb37f, 0xeeff, 0x6fff, 0xffff, 0xbfff, 0xffff, - 0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xfeff, 0xbfbf, 0xfff3, 0x7eff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7f7f, 0xf7ff, 0xbfff, 0xffff, - 0x7fff, 0xf76f, 0xbfff, 0xffb7, 0x6eff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xff7f, 0x7fff, 0xfffd, 0xbfff, 0xffff, - 0x7fff, 0xfcde, 0xbdbf, 0xdf8d, 0x7aff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xb5af, 0xbfff, 0x6ff7, 0x6f7f, 0xbfff, 0xffff, - 0x7fff, 0xfbad, 0xbfdf, 0xf77b, 0x7fff, 0xffff, 0xbfff, 0xffee, - 0x77ff, 0xffff, 0xbfff, 0xfbf7, 0x7f7f, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xf77b, 0xb37f, 0xecf6, 0x6dff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfaf, 0x3000, 0x67c0, 0x061f, 0xbfff, 0xffef, - 0x7fff, 0xfccd, 0xbbb7, 0x7f99, 0x7cff, 0xffff, 0xb7ff, 0xfff5, - 0x6bff, 0xffff, 0xb7ff, 0x3000, 0x66e0, 0x0601, 0xbfff, 0xffdf, - 0x7fff, 0xfccd, 0xbbbe, 0xd519, 0x7cff, 0xffff, 0xafff, 0xffff, - 0x7dff, 0xffff, 0xbd5f, 0x3000, 0x67e0, 0x061f, 0xbfff, 0xffff, - 0x7fff, 0xfcc8, 0xb11f, 0xcc99, 0x78ff, 0xffff, 0xbfff, 0xfff5, - 0x6bff, 0xffff, 0xbbff, 0x3000, 0x67e0, 0x0601, 0xbfff, 0xffff, - 0x7fff, 0xf698, 0xb11f, 0x8033, 0x6eff, 0xffff, 0xbfff, 0xffff, - 0x77ff, 0xffff, 0xbff7, 0xbbbb, 0x73ee, 0x6ee7, 0xb333, 0x31f3, - 0x6666, 0x78c6, 0xaccf, 0xb318, 0x7bcc, 0xccc7, 0xb999, 0x99ff, - 0x7fff, 0xffff, 0xb7ff, 0x3333, 0x6546, 0x6667, 0xb777, 0x74ab, - 0x7777, 0x7d9c, 0xb995, 0x19cd, 0x79dd, 0xddd2, 0xb5dd, 0xddff, - 0x7bff, 0xffff, 0xbffb, 0xfddd, 0x7fdd, 0xdfdf, 0xbfff, 0xffef, - 0x7fff, 0xfff6, 0xacff, 0x337f, 0x7fff, 0xffff, 0xb7ff, 0xffff, - 0x7fff, 0xffff, 0xbffd, 0x5fff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbbdf, 0xddff, 0x7bbf, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xfddf, 0xbfff, 0xffdd, 0x6fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfbf, 0xffdd, 0x6fff, 0xffff, 0xbfff, 0xffff, - 0x7dff, 0xffff, 0xbbff, 0x5fff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xfedf, 0xbbff, 0xbdff, 0x77bf, 0xffff, 0xbfff, 0xffef, - 0x7dff, 0xffff, 0xbfbf, 0xffef, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7ffd, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffb, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7ff7, 0xffbf, 0xbfff, 0xfdff, - 0x7fff, 0xffff, 0xbff7, 0xffdf, 0x7ffe, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xeeff, 0xbfff, 0xffff, 0x7ff7, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffd, 0xffff, 0xbfff, 0xffff, - 0x7ffd, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffbf, 0xbfff, 0xfdff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd, - 0x7bff, 0xffff, 0xb77f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfbf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd, - 0x79ff, 0xffff, 0xb7bf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x75ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbebf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe, - 0x77ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xa59f, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xfff5, - 0x69ff, 0xffff, 0xab7f, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf, - 0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffff, - 0x7dff, 0xffff, 0xbddf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5, - 0x6bff, 0xffff, 0xbabf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0x3333, 0x63e6, 0x6667, 0xb333, 0x31f3, - 0x6666, 0x7ccc, 0xb98f, 0x9999, 0x73cc, 0xccc7, 0xb999, 0x99ff, - 0x7fff, 0xffff, 0xb7bf, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab, - 0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bdd, 0xddd2, 0xb5dd, 0xddff, - 0x7fff, 0xffff, 0xbdff, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xffff, - 0x7fff, 0xffff, 0xbffd, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xf7ff, 0x7fff, 0xfbff, 0xbfff, 0xf7ff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xfbff, 0xbfff, 0xffff, - 0x7dff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xefff, 0x7fff, 0xffff, 0xbfff, 0xf7ff, - 0x7dff, 0xffff, 0xbbbf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xdfff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbeff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffbf, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xfbff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbff7, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xf7ff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xff7f, 0x7fff, 0xffff, 0xbfff, 0xefff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbeff, 0xffff, - 0x7fff, 0xffff, 0xbdff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffbf, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffb, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd, - 0x7fff, 0xffff, 0xbeff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffbf, - 0x7fff, 0xffff, 0xad5f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5, - 0x69ff, 0xffff, 0xabff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7dff, 0xffff, 0xbd9f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5, - 0x69ff, 0xffff, 0xb6bf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe, - 0x75ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfaf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xb6af, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xfffe, - 0x7bff, 0xffff, 0xb9ff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf, - 0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffeb, - 0x7fff, 0xffff, 0xbf5f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe, - 0x77ff, 0xffff, 0xbe9f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x3333, 0x63e6, 0x6667, 0xb333, 0x31f3, - 0x6666, 0x7ccc, 0xb98f, 0x9999, 0x73cc, 0xccc7, 0xb999, 0x99ff, - 0x7fff, 0xffff, 0xbfbf, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab, - 0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bdd, 0xddd2, 0xb5dd, 0xddff, - 0x7fff, 0xffff, 0xbedf, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xfff7, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbefd, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xfffe, 0x7ff7, 0xffbf, 0xbeff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbeff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xff5f, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbffe, 0xffff, - 0x7fff, 0xffff, 0xbf7f, 0xffff, 0x6ff7, 0xffff, 0xbf7f, 0xfeff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbdff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xff7f, 0xbfff, 0xffff, - 0x77ff, 0xffff, 0xbffb, 0xff7f, 0x7fff, 0xbbf7, 0xbfff, 0xbfff, - 0x7fff, 0xffff, 0xbfff, 0xfffb, 0x7fff, 0xffff, 0xbfff, 0xffbf, - 0x77ff, 0xffff, 0xbffe, 0xfffd, 0x6fff, 0xffff, 0xbffe, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbdfd, 0xffff, 0x6fff, 0xdff7, 0xbfff, 0x7fff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffbd, 0x7fff, 0xfdff, 0xbffe, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xfffb, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfea, 0x75ff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffdf, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff7, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbffd, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfdb, 0xb5ff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffbf, - 0x7fff, 0xffff, 0xb6af, 0xefff, 0x7fff, 0x7fff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5, - 0x6bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7dff, 0xffff, 0xb7af, 0xfdff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5, - 0x6bff, 0xffff, 0xbdaf, 0xffff, 0x7ff7, 0xffdf, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffea, - 0x77ff, 0xffff, 0xbbff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x4fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xdeff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbaff, 0xffff, 0x77ff, 0xffbf, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffee, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fef, 0x7fff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xa55f, 0xfebf, 0x67c6, 0x1ebf, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0x9fff, 0x7fff, 0x5fff, 0xffff, 0xb7ff, 0xfff5, - 0x67ff, 0xffff, 0xafff, 0xc2bf, 0x47a6, 0x1ebf, 0xbfff, 0xffdf, - 0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffff, - 0x5fff, 0xffff, 0xb55f, 0xfe7f, 0x67e6, 0x1f3f, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5, - 0x67ff, 0xffff, 0x9fff, 0xc27f, 0x47e6, 0x1f3f, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0x3bb3, 0x73ee, 0xe6e7, 0xb333, 0x31f3, - 0x4666, 0x7ccc, 0xb98f, 0x9999, 0x73cc, 0xccc7, 0xb999, 0x99ff, - 0x7fff, 0xffff, 0xbfff, 0x7337, 0x4546, 0x7677, 0xb777, 0x74ab, - 0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bdd, 0xddd2, 0xb5dd, 0xddff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fdf, 0xdfff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x77ff, 0xffff, 0xbfff, 0xefff, - 0x7fff, 0xffff, 0xbf7f, 0xfff7, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xfffd, 0x7ff7, 0xffff, 0xbfff, 0xffff, - 0x7fdf, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xff7f, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x8fff, 0xfffd, 0x4ff7, 0xffff, 0xbfff, 0xffff, - 0x7fbf, 0xffff, 0xbfff, 0xffef, 0x7fff, 0xff7f, 0x9fff, 0xffff, - 0x5dff, 0xffff, 0xafff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xefff, - 0x7fff, 0xffff, 0x9f7f, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7dff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffb, - 0x77ff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xdfff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x77ee, 0xffff, 0xbfff, 0xdfff, - 0x7fff, 0xefff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xefff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xa55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xfffd, - 0x7bff, 0xffff, 0xafff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xa55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd, - 0x7bff, 0xffff, 0xaaff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffb, - 0x77ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbaff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffee, - 0x77ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x855f, 0xffff, 0x5fdf, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0x97ff, 0xfff5, - 0x4bff, 0xffff, 0xafff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf, - 0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffff, - 0x7fff, 0xffff, 0xb55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5, - 0x6bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0x3333, 0x43e6, 0x6667, 0xb333, 0x31f3, - 0x6666, 0x7ccc, 0xb98f, 0x9999, 0x73cc, 0xccc7, 0xb999, 0x99ff, - 0x7fff, 0xffff, 0xbfff, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab, - 0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bdd, 0xddd2, 0xb5dd, 0xddff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fdf, 0xffff, 0xbfff, 0xffef, - 0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xfeff, 0x7fff, 0xbfff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xfff7, - 0x7fff, 0xffff, 0xafff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7dff, 0xffff, 0xafff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7dff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xf7ff, - 0x7fff, 0xffff, 0xbfbf, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffef, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x5fff, 0xefff, 0xbfff, 0xffef, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xf7ff, - 0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfdf, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fef, 0xffff, 0x9fff, 0xefff, - 0x5fff, 0xefff, 0xbfff, 0xdfff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffbd, 0x7fff, 0xbdff, 0xbfff, 0xf7ff, - 0x7fff, 0xefff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff7, 0xfdff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xdfff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xff7e, 0x7fff, 0xdfff, 0xbfff, 0xdbff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffef, 0x7ffd, 0xdfff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xefff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xfffb, 0x77ef, 0xffff, 0xbfdd, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xfffe, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffef, 0x5ffd, 0xbfff, 0xbfef, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xefff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xfef1, 0x67e7, 0xbfff, 0x9fed, 0xeffd, - 0x53ff, 0xfff9, 0xb77f, 0xffff, 0x7fff, 0xb99f, 0xbccf, 0xffff, - 0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbffc, 0xffff, 0x7ff3, 0xfffe, 0xaf9e, 0x7cff, - 0x7fff, 0xffe7, 0x93e7, 0xffff, 0x5f3e, 0x79f3, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff, - 0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, - 0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff, -} }; - -const std::array block_1 { { - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, -} }; - -} /* namespace cpld */ -} /* namespace portapack */ From f296fcdc29dfd7c116216c018f2cea3518d5e564 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 10 Jul 2016 13:58:17 -0700 Subject: [PATCH 130/165] Fix wrong firmware URL posted to IRC by Travis-CI. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 64dd7d69..0c75d2be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ notifications: - "Change view : %{compare_url}" - "Build details : %{build_url}" # TODO: The "build_number.1" in this URL is almost certainly wrong, but correct value not available from Travis? - - "Firmware download : https://portapack-h1-builds.s3.amazonaws.com/%{repository_slug}/%{build_number}/%{build_number}.1/firmware/portapack-h1-firmware-%{commit}.tar.bz2" + - "Firmware download : https://portapack-h1-builds.s3.amazonaws.com/%{repository_slug}/%{build_number}/%{build_number}.1/build/firmware/portapack-h1-firmware-%{commit}.tar.bz2" before_script: - wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2 -O /tmp/gcc-arm.tar.bz2 From 1cd5a1676c06d0a5c7f326e077f0913b9b1db40d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 10 Jul 2016 15:00:34 -0700 Subject: [PATCH 131/165] Ignore all CPLD output_files/ except *.svf. --- hardware/.gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hardware/.gitignore b/hardware/.gitignore index 43c181df..ddc0d214 100644 --- a/hardware/.gitignore +++ b/hardware/.gitignore @@ -7,7 +7,12 @@ tb2_ie_info.xml **/cpld/db/ **/cpld/incremental_db/ -**/cpld/output_files/ +**/cpld/output_files/*.done +**/cpld/output_files/*.smsg +**/cpld/output_files/*.summary +**/cpld/output_files/*.jdi +**/cpld/output_files/*.pin +**/cpld/output_files/*.pof **/cpld/simulation/ # KiCad From 2add96d42d1e9c5dd625ae6ae3c39d8d88396d4d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 10 Jul 2016 15:01:04 -0700 Subject: [PATCH 132/165] CPLD: Add .svf output file so CMake can generate data for firmware. --- .../cpld/output_files/portapack_h1_cpld.svf | 11646 ++++++++++++++++ 1 file changed, 11646 insertions(+) create mode 100644 hardware/portapack_h1/cpld/output_files/portapack_h1_cpld.svf diff --git a/hardware/portapack_h1/cpld/output_files/portapack_h1_cpld.svf b/hardware/portapack_h1/cpld/output_files/portapack_h1_cpld.svf new file mode 100644 index 00000000..c039e066 --- /dev/null +++ b/hardware/portapack_h1/cpld/output_files/portapack_h1_cpld.svf @@ -0,0 +1,11646 @@ +!Copyright (C) 1991-2014 Altera Corporation. All rights reserved. +!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, the Altera Quartus II License Agreement, +!the 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 SVF converter 14.1 +! +!Device #1: 5M40Z - /mnt/hgfs/src/portapack-hackrf/hardware/portapack_h1/cpld/output_files/portapack_h1_cpld.pof Fri Aug 21 12:12:34 2015 +! +!NOTE "USERCODE" "0018AF0E"; +! +!NOTE "CHECKSUM" "0018B286"; +! +! +! +FREQUENCY 1.80E+07 HZ; +! +! +! +TRST ABSENT; +ENDDR IDLE; +ENDIR IRPAUSE; +STATE IDLE; +SIR 10 TDI (2CC); +RUNTEST IDLE 18003 TCK ENDSTATE IDLE; +! +! +! +!CHECKING SILICON ID +! +! +! +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0089); +SIR 10 TDI (205); +RUNTEST 93 TCK; +SDR 16 TDI (FFFF) TDO (8232) MASK (FFFF); +SDR 16 TDI (FFFF) TDO (2AA2); +SDR 16 TDI (FFFF) TDO (4A82); +SDR 16 TDI (FFFF) TDO (8C0C); +SDR 16 TDI (FFFF) TDO (0000); +! +! +! +!BULK ERASE +! +! +! +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0011); +SIR 10 TDI (2F2); +RUNTEST 9000003 TCK; +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0001); +SIR 10 TDI (2F2); +RUNTEST 9000003 TCK; +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0000); +SIR 10 TDI (2F2); +RUNTEST 9000003 TCK; +! +! +! +!PROGRAM +! +! +! +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0000); +SIR 10 TDI (2F4); +RUNTEST 93 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFC); +RUNTEST 1800 TCK; +SDR 16 TDI (F9E7); +RUNTEST 1800 TCK; +SDR 16 TDI (79FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (AF9E); +RUNTEST 1800 TCK; +SDR 16 TDI (7CFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBE7); +RUNTEST 1800 TCK; +SDR 16 TDI (B3F7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7F3F); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFB); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (67FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (E7F9); +RUNTEST 1800 TCK; +SDR 16 TDI (723F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF9); +RUNTEST 1800 TCK; +SDR 16 TDI (B77F); +RUNTEST 1800 TCK; +SDR 16 TDI (CCCF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B99F); +RUNTEST 1800 TCK; +SDR 16 TDI (BCCC); +RUNTEST 1800 TCK; +SDR 16 TDI (CFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEB); +RUNTEST 1800 TCK; +SDR 16 TDI (77F3); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFE6); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBFE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDB); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF5); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7EFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDBB); +RUNTEST 1800 TCK; +SDR 16 TDI (77EF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7EEF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7EF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7EFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B5FD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (ADFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF5F); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F6FF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBCB); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FAFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFD5); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (A55F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (DEEF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEB); +RUNTEST 1800 TCK; +SDR 16 TDI (6BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B55F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BABF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFB); +RUNTEST 1800 TCK; +SDR 16 TDI (F9BF); +RUNTEST 1800 TCK; +SDR 16 TDI (BAFE); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDE); +RUNTEST 1800 TCK; +SDR 16 TDI (BFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (35FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FD2); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBC); +RUNTEST 1800 TCK; +SDR 16 TDI (C7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7AF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DDEE); +RUNTEST 1800 TCK; +SDR 16 TDI (B9FF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFD); +RUNTEST 1800 TCK; +SDR 16 TDI (EA9F); +RUNTEST 1800 TCK; +SDR 16 TDI (BEFB); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEAF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFD); +RUNTEST 1800 TCK; +SDR 16 TDI (0DDF); +RUNTEST 1800 TCK; +SDR 16 TDI (B598); +RUNTEST 1800 TCK; +SDR 16 TDI (5E74); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B65F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFC); +RUNTEST 1800 TCK; +SDR 16 TDI (0DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (BD99); +RUNTEST 1800 TCK; +SDR 16 TDI (1E6A); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7F08); +RUNTEST 1800 TCK; +SDR 16 TDI (388F); +RUNTEST 1800 TCK; +SDR 16 TDI (B89E); +RUNTEST 1800 TCK; +SDR 16 TDI (887F); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B6F7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7F0C); +RUNTEST 1800 TCK; +SDR 16 TDI (388F); +RUNTEST 1800 TCK; +SDR 16 TDI (B89F); +RUNTEST 1800 TCK; +SDR 16 TDI (983B); +RUNTEST 1800 TCK; +SDR 16 TDI (67FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (3333); +RUNTEST 1800 TCK; +SDR 16 TDI (63E6); +RUNTEST 1800 TCK; +SDR 16 TDI (6667); +RUNTEST 1800 TCK; +SDR 16 TDI (B333); +RUNTEST 1800 TCK; +SDR 16 TDI (31F3); +RUNTEST 1800 TCK; +SDR 16 TDI (6666); +RUNTEST 1800 TCK; +SDR 16 TDI (7CCC); +RUNTEST 1800 TCK; +SDR 16 TDI (B98F); +RUNTEST 1800 TCK; +SDR 16 TDI (9999); +RUNTEST 1800 TCK; +SDR 16 TDI (73E8); +RUNTEST 1800 TCK; +SDR 16 TDI (C445); +RUNTEST 1800 TCK; +SDR 16 TDI (B938); +RUNTEST 1800 TCK; +SDR 16 TDI (88FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (6957); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (B777); +RUNTEST 1800 TCK; +SDR 16 TDI (74AB); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (7DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (BBA5); +RUNTEST 1800 TCK; +SDR 16 TDI (5DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (7BCD); +RUNTEST 1800 TCK; +SDR 16 TDI (DCCA); +RUNTEST 1800 TCK; +SDR 16 TDI (B19D); +RUNTEST 1800 TCK; +SDR 16 TDI (DDFB); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (E66F); +RUNTEST 1800 TCK; +SDR 16 TDI (B37F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FEB); +RUNTEST 1800 TCK; +SDR 16 TDI (EEDF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FCFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EEEE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFB); +RUNTEST 1800 TCK; +SDR 16 TDI (FBBF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFA); +RUNTEST 1800 TCK; +SDR 16 TDI (EFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FEF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFDD); +RUNTEST 1800 TCK; +SDR 16 TDI (FD7A); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEBE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FB7F); +RUNTEST 1800 TCK; +SDR 16 TDI (BF9F); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BAFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFDE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFB); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFB); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFF3); +RUNTEST 1800 TCK; +SDR 16 TDI (BBF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (BEAF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFB); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDEE); +RUNTEST 1800 TCK; +SDR 16 TDI (B7F7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBEF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBFE); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEDF); +RUNTEST 1800 TCK; +SDR 16 TDI (6DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FEF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (ADBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFD7); +RUNTEST 1800 TCK; +SDR 16 TDI (6EFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BADF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BD7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBF9); +RUNTEST 1800 TCK; +SDR 16 TDI (B3FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BE5F); +RUNTEST 1800 TCK; +SDR 16 TDI (FF77); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEFD); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEEE); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FB3B); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEA); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (D7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBAF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF4); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDAF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7BA); +RUNTEST 1800 TCK; +SDR 16 TDI (B37F); +RUNTEST 1800 TCK; +SDR 16 TDI (EEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF3); +RUNTEST 1800 TCK; +SDR 16 TDI (7EFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7F7F); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F76F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFB7); +RUNTEST 1800 TCK; +SDR 16 TDI (6EFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FCDE); +RUNTEST 1800 TCK; +SDR 16 TDI (BDBF); +RUNTEST 1800 TCK; +SDR 16 TDI (DF8D); +RUNTEST 1800 TCK; +SDR 16 TDI (7AFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B5AF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (6FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (6F7F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBAD); +RUNTEST 1800 TCK; +SDR 16 TDI (BFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (F77B); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEE); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7F7F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F77B); +RUNTEST 1800 TCK; +SDR 16 TDI (B37F); +RUNTEST 1800 TCK; +SDR 16 TDI (ECF6); +RUNTEST 1800 TCK; +SDR 16 TDI (6DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFAF); +RUNTEST 1800 TCK; +SDR 16 TDI (3000); +RUNTEST 1800 TCK; +SDR 16 TDI (67C0); +RUNTEST 1800 TCK; +SDR 16 TDI (061F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FCCD); +RUNTEST 1800 TCK; +SDR 16 TDI (BBB7); +RUNTEST 1800 TCK; +SDR 16 TDI (7F99); +RUNTEST 1800 TCK; +SDR 16 TDI (7CFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (6BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (3000); +RUNTEST 1800 TCK; +SDR 16 TDI (66E0); +RUNTEST 1800 TCK; +SDR 16 TDI (0601); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FCCD); +RUNTEST 1800 TCK; +SDR 16 TDI (BBBE); +RUNTEST 1800 TCK; +SDR 16 TDI (D519); +RUNTEST 1800 TCK; +SDR 16 TDI (7CFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BD5F); +RUNTEST 1800 TCK; +SDR 16 TDI (3000); +RUNTEST 1800 TCK; +SDR 16 TDI (67E0); +RUNTEST 1800 TCK; +SDR 16 TDI (061F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FCC8); +RUNTEST 1800 TCK; +SDR 16 TDI (B11F); +RUNTEST 1800 TCK; +SDR 16 TDI (CC99); +RUNTEST 1800 TCK; +SDR 16 TDI (78FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (6BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (3000); +RUNTEST 1800 TCK; +SDR 16 TDI (67E0); +RUNTEST 1800 TCK; +SDR 16 TDI (0601); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F698); +RUNTEST 1800 TCK; +SDR 16 TDI (B11F); +RUNTEST 1800 TCK; +SDR 16 TDI (8033); +RUNTEST 1800 TCK; +SDR 16 TDI (6EFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (BBBB); +RUNTEST 1800 TCK; +SDR 16 TDI (73EE); +RUNTEST 1800 TCK; +SDR 16 TDI (6EE7); +RUNTEST 1800 TCK; +SDR 16 TDI (B333); +RUNTEST 1800 TCK; +SDR 16 TDI (31F3); +RUNTEST 1800 TCK; +SDR 16 TDI (6666); +RUNTEST 1800 TCK; +SDR 16 TDI (78C6); +RUNTEST 1800 TCK; +SDR 16 TDI (ACCF); +RUNTEST 1800 TCK; +SDR 16 TDI (B318); +RUNTEST 1800 TCK; +SDR 16 TDI (7BCC); +RUNTEST 1800 TCK; +SDR 16 TDI (CCC7); +RUNTEST 1800 TCK; +SDR 16 TDI (B999); +RUNTEST 1800 TCK; +SDR 16 TDI (99FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (3333); +RUNTEST 1800 TCK; +SDR 16 TDI (6546); +RUNTEST 1800 TCK; +SDR 16 TDI (6667); +RUNTEST 1800 TCK; +SDR 16 TDI (B777); +RUNTEST 1800 TCK; +SDR 16 TDI (74AB); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (7D9C); +RUNTEST 1800 TCK; +SDR 16 TDI (B995); +RUNTEST 1800 TCK; +SDR 16 TDI (19CD); +RUNTEST 1800 TCK; +SDR 16 TDI (79DD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDD2); +RUNTEST 1800 TCK; +SDR 16 TDI (B5DD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (FDDD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDD); +RUNTEST 1800 TCK; +SDR 16 TDI (DFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF6); +RUNTEST 1800 TCK; +SDR 16 TDI (ACFF); +RUNTEST 1800 TCK; +SDR 16 TDI (337F); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBDF); +RUNTEST 1800 TCK; +SDR 16 TDI (DDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7BBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDDF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDD); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDD); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEDF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (77BF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFB); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B77F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (79FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7BF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (75FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (A59F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (69FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AB7F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (6BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BABF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (3333); +RUNTEST 1800 TCK; +SDR 16 TDI (63E6); +RUNTEST 1800 TCK; +SDR 16 TDI (6667); +RUNTEST 1800 TCK; +SDR 16 TDI (B333); +RUNTEST 1800 TCK; +SDR 16 TDI (31F3); +RUNTEST 1800 TCK; +SDR 16 TDI (6666); +RUNTEST 1800 TCK; +SDR 16 TDI (7CCC); +RUNTEST 1800 TCK; +SDR 16 TDI (B98F); +RUNTEST 1800 TCK; +SDR 16 TDI (9999); +RUNTEST 1800 TCK; +SDR 16 TDI (73CC); +RUNTEST 1800 TCK; +SDR 16 TDI (CCC7); +RUNTEST 1800 TCK; +SDR 16 TDI (B999); +RUNTEST 1800 TCK; +SDR 16 TDI (99FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7BF); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (6957); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (B777); +RUNTEST 1800 TCK; +SDR 16 TDI (74AB); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (7DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (BBA5); +RUNTEST 1800 TCK; +SDR 16 TDI (5DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (7BDD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDD2); +RUNTEST 1800 TCK; +SDR 16 TDI (B5DD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AD5F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (69FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (ABFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BD9F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (69FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B6BF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (75FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFAF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B6AF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B9FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEB); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BF5F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BE9F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (3333); +RUNTEST 1800 TCK; +SDR 16 TDI (63E6); +RUNTEST 1800 TCK; +SDR 16 TDI (6667); +RUNTEST 1800 TCK; +SDR 16 TDI (B333); +RUNTEST 1800 TCK; +SDR 16 TDI (31F3); +RUNTEST 1800 TCK; +SDR 16 TDI (6666); +RUNTEST 1800 TCK; +SDR 16 TDI (7CCC); +RUNTEST 1800 TCK; +SDR 16 TDI (B98F); +RUNTEST 1800 TCK; +SDR 16 TDI (9999); +RUNTEST 1800 TCK; +SDR 16 TDI (73CC); +RUNTEST 1800 TCK; +SDR 16 TDI (CCC7); +RUNTEST 1800 TCK; +SDR 16 TDI (B999); +RUNTEST 1800 TCK; +SDR 16 TDI (99FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (6957); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (B777); +RUNTEST 1800 TCK; +SDR 16 TDI (74AB); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (7DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (BBA5); +RUNTEST 1800 TCK; +SDR 16 TDI (5DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (7BDD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDD2); +RUNTEST 1800 TCK; +SDR 16 TDI (B5DD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF5F); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (6FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (FEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBF7); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (6FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFEA); +RUNTEST 1800 TCK; +SDR 16 TDI (75FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFDB); +RUNTEST 1800 TCK; +SDR 16 TDI (B5FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B6AF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (6BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7AF); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (6BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDAF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEA); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (4FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BAFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (A55F); +RUNTEST 1800 TCK; +SDR 16 TDI (FEBF); +RUNTEST 1800 TCK; +SDR 16 TDI (67C6); +RUNTEST 1800 TCK; +SDR 16 TDI (1EBF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (67FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (C2BF); +RUNTEST 1800 TCK; +SDR 16 TDI (47A6); +RUNTEST 1800 TCK; +SDR 16 TDI (1EBF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B55F); +RUNTEST 1800 TCK; +SDR 16 TDI (FE7F); +RUNTEST 1800 TCK; +SDR 16 TDI (67E6); +RUNTEST 1800 TCK; +SDR 16 TDI (1F3F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (67FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (C27F); +RUNTEST 1800 TCK; +SDR 16 TDI (47E6); +RUNTEST 1800 TCK; +SDR 16 TDI (1F3F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (3BB3); +RUNTEST 1800 TCK; +SDR 16 TDI (73EE); +RUNTEST 1800 TCK; +SDR 16 TDI (E6E7); +RUNTEST 1800 TCK; +SDR 16 TDI (B333); +RUNTEST 1800 TCK; +SDR 16 TDI (31F3); +RUNTEST 1800 TCK; +SDR 16 TDI (4666); +RUNTEST 1800 TCK; +SDR 16 TDI (7CCC); +RUNTEST 1800 TCK; +SDR 16 TDI (B98F); +RUNTEST 1800 TCK; +SDR 16 TDI (9999); +RUNTEST 1800 TCK; +SDR 16 TDI (73CC); +RUNTEST 1800 TCK; +SDR 16 TDI (CCC7); +RUNTEST 1800 TCK; +SDR 16 TDI (B999); +RUNTEST 1800 TCK; +SDR 16 TDI (99FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7337); +RUNTEST 1800 TCK; +SDR 16 TDI (4546); +RUNTEST 1800 TCK; +SDR 16 TDI (7677); +RUNTEST 1800 TCK; +SDR 16 TDI (B777); +RUNTEST 1800 TCK; +SDR 16 TDI (74AB); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (7DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (BBA5); +RUNTEST 1800 TCK; +SDR 16 TDI (5DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (7BDD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDD2); +RUNTEST 1800 TCK; +SDR 16 TDI (B5DD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (8FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (4FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7F); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9F7F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (77EE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (A55F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (A55F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AAFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BAFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEE); +RUNTEST 1800 TCK; +SDR 16 TDI (77FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (855F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (97FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (4BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B55F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF5); +RUNTEST 1800 TCK; +SDR 16 TDI (6BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (3333); +RUNTEST 1800 TCK; +SDR 16 TDI (43E6); +RUNTEST 1800 TCK; +SDR 16 TDI (6667); +RUNTEST 1800 TCK; +SDR 16 TDI (B333); +RUNTEST 1800 TCK; +SDR 16 TDI (31F3); +RUNTEST 1800 TCK; +SDR 16 TDI (6666); +RUNTEST 1800 TCK; +SDR 16 TDI (7CCC); +RUNTEST 1800 TCK; +SDR 16 TDI (B98F); +RUNTEST 1800 TCK; +SDR 16 TDI (9999); +RUNTEST 1800 TCK; +SDR 16 TDI (73CC); +RUNTEST 1800 TCK; +SDR 16 TDI (CCC7); +RUNTEST 1800 TCK; +SDR 16 TDI (B999); +RUNTEST 1800 TCK; +SDR 16 TDI (99FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (6957); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (B777); +RUNTEST 1800 TCK; +SDR 16 TDI (74AB); +RUNTEST 1800 TCK; +SDR 16 TDI (7777); +RUNTEST 1800 TCK; +SDR 16 TDI (7DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (BBA5); +RUNTEST 1800 TCK; +SDR 16 TDI (5DDD); +RUNTEST 1800 TCK; +SDR 16 TDI (7BDD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDD2); +RUNTEST 1800 TCK; +SDR 16 TDI (B5DD); +RUNTEST 1800 TCK; +SDR 16 TDI (DDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF7); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (AFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7DFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFBF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFDF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FEF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFBD); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (F7FF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF7); +RUNTEST 1800 TCK; +SDR 16 TDI (FDFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FF7E); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (DBFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFD); +RUNTEST 1800 TCK; +SDR 16 TDI (DFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFB); +RUNTEST 1800 TCK; +SDR 16 TDI (77EF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFDD); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFD); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFEF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FEF1); +RUNTEST 1800 TCK; +SDR 16 TDI (67E7); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FED); +RUNTEST 1800 TCK; +SDR 16 TDI (EFFD); +RUNTEST 1800 TCK; +SDR 16 TDI (53FF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFF9); +RUNTEST 1800 TCK; +SDR 16 TDI (B77F); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (B99F); +RUNTEST 1800 TCK; +SDR 16 TDI (BCCF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFC); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FF3); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFE); +RUNTEST 1800 TCK; +SDR 16 TDI (AF9E); +RUNTEST 1800 TCK; +SDR 16 TDI (7CFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFE7); +RUNTEST 1800 TCK; +SDR 16 TDI (93E7); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5F3E); +RUNTEST 1800 TCK; +SDR 16 TDI (79F3); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (9FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (5FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (7FFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0001); +SIR 10 TDI (2F4); +RUNTEST 93 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +! +! +! +!VERIFY +! +! +! +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0000); +SIR 10 TDI (205); +RUNTEST 93 TCK; +SDR 16 TDI (FFFF) TDO (7FFF) MASK (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFC); +SDR 16 TDI (FFFF) TDO (F9E7); +SDR 16 TDI (FFFF) TDO (79FF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (AF9E); +SDR 16 TDI (FFFF) TDO (7CFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FBE7); +SDR 16 TDI (FFFF) TDO (B3F7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7F3F); +SDR 16 TDI (FFFF) TDO (7DFB); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (67FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FEFD); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (E7F9); +SDR 16 TDI (FFFF) TDO (723F); +SDR 16 TDI (FFFF) TDO (FFF9); +SDR 16 TDI (FFFF) TDO (B77F); +SDR 16 TDI (FFFF) TDO (CCCF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (B99F); +SDR 16 TDI (FFFF) TDO (BCCC); +SDR 16 TDI (FFFF) TDO (CFFE); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEB); +SDR 16 TDI (FFFF) TDO (77F3); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFE6); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FBFE); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFEF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDB); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF5); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7EFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FDBB); +SDR 16 TDI (FFFF) TDO (77EF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (7EEF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FEF7); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7EF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7EFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FEFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B5FD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (ADFF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (7FFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFEF); +SDR 16 TDI (FFFF) TDO (FF5F); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (F6FF); +SDR 16 TDI (FFFF) TDO (BBCB); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FAFF); +SDR 16 TDI (FFFF) TDO (BFD5); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (A55F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (DEEF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FDFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFB); +SDR 16 TDI (FFFF) TDO (FFEB); +SDR 16 TDI (FFFF) TDO (6BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B55F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDFF); +SDR 16 TDI (FFFF) TDO (DFF5); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BABF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFB); +SDR 16 TDI (FFFF) TDO (F9BF); +SDR 16 TDI (FFFF) TDO (BAFE); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFE); +SDR 16 TDI (FFFF) TDO (FFDE); +SDR 16 TDI (FFFF) TDO (BFDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (35FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FD2); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFBC); +SDR 16 TDI (FFFF) TDO (C7FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7AF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (DDEE); +SDR 16 TDI (FFFF) TDO (B9FF); +SDR 16 TDI (FFFF) TDO (BDFF); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFD); +SDR 16 TDI (FFFF) TDO (EA9F); +SDR 16 TDI (FFFF) TDO (BEFB); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEAF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFD); +SDR 16 TDI (FFFF) TDO (0DDF); +SDR 16 TDI (FFFF) TDO (B598); +SDR 16 TDI (FFFF) TDO (5E74); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B65F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFC); +SDR 16 TDI (FFFF) TDO (0DDD); +SDR 16 TDI (FFFF) TDO (BD99); +SDR 16 TDI (FFFF) TDO (1E6A); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7F08); +SDR 16 TDI (FFFF) TDO (388F); +SDR 16 TDI (FFFF) TDO (B89E); +SDR 16 TDI (FFFF) TDO (887F); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B6F7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7F0C); +SDR 16 TDI (FFFF) TDO (388F); +SDR 16 TDI (FFFF) TDO (B89F); +SDR 16 TDI (FFFF) TDO (983B); +SDR 16 TDI (FFFF) TDO (67FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (3333); +SDR 16 TDI (FFFF) TDO (63E6); +SDR 16 TDI (FFFF) TDO (6667); +SDR 16 TDI (FFFF) TDO (B333); +SDR 16 TDI (FFFF) TDO (31F3); +SDR 16 TDI (FFFF) TDO (6666); +SDR 16 TDI (FFFF) TDO (7CCC); +SDR 16 TDI (FFFF) TDO (B98F); +SDR 16 TDI (FFFF) TDO (9999); +SDR 16 TDI (FFFF) TDO (73E8); +SDR 16 TDI (FFFF) TDO (C445); +SDR 16 TDI (FFFF) TDO (B938); +SDR 16 TDI (FFFF) TDO (88FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (6957); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (B777); +SDR 16 TDI (FFFF) TDO (74AB); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (7DDD); +SDR 16 TDI (FFFF) TDO (BBA5); +SDR 16 TDI (FFFF) TDO (5DDD); +SDR 16 TDI (FFFF) TDO (7BCD); +SDR 16 TDI (FFFF) TDO (DCCA); +SDR 16 TDI (FFFF) TDO (B19D); +SDR 16 TDI (FFFF) TDO (DDFB); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (E66F); +SDR 16 TDI (FFFF) TDO (B37F); +SDR 16 TDI (FFFF) TDO (FFDE); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FEB); +SDR 16 TDI (FFFF) TDO (EEDF); +SDR 16 TDI (FFFF) TDO (BFDF); +SDR 16 TDI (FFFF) TDO (FCFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (EEEE); +SDR 16 TDI (FFFF) TDO (7FFB); +SDR 16 TDI (FFFF) TDO (FBBF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFA); +SDR 16 TDI (FFFF) TDO (EFDF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FEF); +SDR 16 TDI (FFFF) TDO (FEFF); +SDR 16 TDI (FFFF) TDO (BFDD); +SDR 16 TDI (FFFF) TDO (FD7A); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEBE); +SDR 16 TDI (FFFF) TDO (FFF7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FB7F); +SDR 16 TDI (FFFF) TDO (BF9F); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFEF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BAFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FDFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DFDE); +SDR 16 TDI (FFFF) TDO (7FFB); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FD); +SDR 16 TDI (FFFF) TDO (FFF7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FDFB); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EDFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFF3); +SDR 16 TDI (FFFF) TDO (BBF7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (BEAF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (BFBE); +SDR 16 TDI (FFFF) TDO (7FFB); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDEE); +SDR 16 TDI (FFFF) TDO (B7F7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FBEF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FBFE); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FEDF); +SDR 16 TDI (FFFF) TDO (6DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (EFDF); +SDR 16 TDI (FFFF) TDO (7FEF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFF7); +SDR 16 TDI (FFFF) TDO (ADBF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FDFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFD7); +SDR 16 TDI (FFFF) TDO (6EFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BADF); +SDR 16 TDI (FFFF) TDO (7BD7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FBF9); +SDR 16 TDI (FFFF) TDO (B3FF); +SDR 16 TDI (FFFF) TDO (FEFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BE5F); +SDR 16 TDI (FFFF) TDO (FF77); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FEFD); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FEEE); +SDR 16 TDI (FFFF) TDO (BFBF); +SDR 16 TDI (FFFF) TDO (FB3B); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEA); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (D7FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBAF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF4); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDAF); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (F7BA); +SDR 16 TDI (FFFF) TDO (B37F); +SDR 16 TDI (FFFF) TDO (EEFF); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FEFF); +SDR 16 TDI (FFFF) TDO (BFBF); +SDR 16 TDI (FFFF) TDO (FFF3); +SDR 16 TDI (FFFF) TDO (7EFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7F7F); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (F76F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFB7); +SDR 16 TDI (FFFF) TDO (6EFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FCDE); +SDR 16 TDI (FFFF) TDO (BDBF); +SDR 16 TDI (FFFF) TDO (DF8D); +SDR 16 TDI (FFFF) TDO (7AFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B5AF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (6FF7); +SDR 16 TDI (FFFF) TDO (6F7F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FBAD); +SDR 16 TDI (FFFF) TDO (BFDF); +SDR 16 TDI (FFFF) TDO (F77B); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEE); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FBF7); +SDR 16 TDI (FFFF) TDO (7F7F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (F77B); +SDR 16 TDI (FFFF) TDO (B37F); +SDR 16 TDI (FFFF) TDO (ECF6); +SDR 16 TDI (FFFF) TDO (6DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFAF); +SDR 16 TDI (FFFF) TDO (3000); +SDR 16 TDI (FFFF) TDO (67C0); +SDR 16 TDI (FFFF) TDO (061F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FCCD); +SDR 16 TDI (FFFF) TDO (BBB7); +SDR 16 TDI (FFFF) TDO (7F99); +SDR 16 TDI (FFFF) TDO (7CFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (6BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (3000); +SDR 16 TDI (FFFF) TDO (66E0); +SDR 16 TDI (FFFF) TDO (0601); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FCCD); +SDR 16 TDI (FFFF) TDO (BBBE); +SDR 16 TDI (FFFF) TDO (D519); +SDR 16 TDI (FFFF) TDO (7CFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BD5F); +SDR 16 TDI (FFFF) TDO (3000); +SDR 16 TDI (FFFF) TDO (67E0); +SDR 16 TDI (FFFF) TDO (061F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FCC8); +SDR 16 TDI (FFFF) TDO (B11F); +SDR 16 TDI (FFFF) TDO (CC99); +SDR 16 TDI (FFFF) TDO (78FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (6BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBFF); +SDR 16 TDI (FFFF) TDO (3000); +SDR 16 TDI (FFFF) TDO (67E0); +SDR 16 TDI (FFFF) TDO (0601); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (F698); +SDR 16 TDI (FFFF) TDO (B11F); +SDR 16 TDI (FFFF) TDO (8033); +SDR 16 TDI (FFFF) TDO (6EFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFF7); +SDR 16 TDI (FFFF) TDO (BBBB); +SDR 16 TDI (FFFF) TDO (73EE); +SDR 16 TDI (FFFF) TDO (6EE7); +SDR 16 TDI (FFFF) TDO (B333); +SDR 16 TDI (FFFF) TDO (31F3); +SDR 16 TDI (FFFF) TDO (6666); +SDR 16 TDI (FFFF) TDO (78C6); +SDR 16 TDI (FFFF) TDO (ACCF); +SDR 16 TDI (FFFF) TDO (B318); +SDR 16 TDI (FFFF) TDO (7BCC); +SDR 16 TDI (FFFF) TDO (CCC7); +SDR 16 TDI (FFFF) TDO (B999); +SDR 16 TDI (FFFF) TDO (99FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (3333); +SDR 16 TDI (FFFF) TDO (6546); +SDR 16 TDI (FFFF) TDO (6667); +SDR 16 TDI (FFFF) TDO (B777); +SDR 16 TDI (FFFF) TDO (74AB); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (7D9C); +SDR 16 TDI (FFFF) TDO (B995); +SDR 16 TDI (FFFF) TDO (19CD); +SDR 16 TDI (FFFF) TDO (79DD); +SDR 16 TDI (FFFF) TDO (DDD2); +SDR 16 TDI (FFFF) TDO (B5DD); +SDR 16 TDI (FFFF) TDO (DDFF); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFB); +SDR 16 TDI (FFFF) TDO (FDDD); +SDR 16 TDI (FFFF) TDO (7FDD); +SDR 16 TDI (FFFF) TDO (DFDF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFF6); +SDR 16 TDI (FFFF) TDO (ACFF); +SDR 16 TDI (FFFF) TDO (337F); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBDF); +SDR 16 TDI (FFFF) TDO (DDFF); +SDR 16 TDI (FFFF) TDO (7BBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FDDF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDD); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFBF); +SDR 16 TDI (FFFF) TDO (FFDD); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FEDF); +SDR 16 TDI (FFFF) TDO (BBFF); +SDR 16 TDI (FFFF) TDO (BDFF); +SDR 16 TDI (FFFF) TDO (77BF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFBF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFB); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FDFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFF7); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EEFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FDFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B77F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (79FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7BF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (75FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (A59F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (69FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AB7F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (6BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BABF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (3333); +SDR 16 TDI (FFFF) TDO (63E6); +SDR 16 TDI (FFFF) TDO (6667); +SDR 16 TDI (FFFF) TDO (B333); +SDR 16 TDI (FFFF) TDO (31F3); +SDR 16 TDI (FFFF) TDO (6666); +SDR 16 TDI (FFFF) TDO (7CCC); +SDR 16 TDI (FFFF) TDO (B98F); +SDR 16 TDI (FFFF) TDO (9999); +SDR 16 TDI (FFFF) TDO (73CC); +SDR 16 TDI (FFFF) TDO (CCC7); +SDR 16 TDI (FFFF) TDO (B999); +SDR 16 TDI (FFFF) TDO (99FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7BF); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (6957); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (B777); +SDR 16 TDI (FFFF) TDO (74AB); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (7DDD); +SDR 16 TDI (FFFF) TDO (BBA5); +SDR 16 TDI (FFFF) TDO (5DDD); +SDR 16 TDI (FFFF) TDO (7BDD); +SDR 16 TDI (FFFF) TDO (DDD2); +SDR 16 TDI (FFFF) TDO (B5DD); +SDR 16 TDI (FFFF) TDO (DDFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FBFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FBFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FBFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AD5F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (69FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (ABFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BD9F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (69FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B6BF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (75FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFAF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B6AF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B9FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFEB); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BF5F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BE9F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (3333); +SDR 16 TDI (FFFF) TDO (63E6); +SDR 16 TDI (FFFF) TDO (6667); +SDR 16 TDI (FFFF) TDO (B333); +SDR 16 TDI (FFFF) TDO (31F3); +SDR 16 TDI (FFFF) TDO (6666); +SDR 16 TDI (FFFF) TDO (7CCC); +SDR 16 TDI (FFFF) TDO (B98F); +SDR 16 TDI (FFFF) TDO (9999); +SDR 16 TDI (FFFF) TDO (73CC); +SDR 16 TDI (FFFF) TDO (CCC7); +SDR 16 TDI (FFFF) TDO (B999); +SDR 16 TDI (FFFF) TDO (99FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFBF); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (6957); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (B777); +SDR 16 TDI (FFFF) TDO (74AB); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (7DDD); +SDR 16 TDI (FFFF) TDO (BBA5); +SDR 16 TDI (FFFF) TDO (5DDD); +SDR 16 TDI (FFFF) TDO (7BDD); +SDR 16 TDI (FFFF) TDO (DDD2); +SDR 16 TDI (FFFF) TDO (B5DD); +SDR 16 TDI (FFFF) TDO (DDFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFF7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (BEFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BEFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FF5F); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BF7F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (6FF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BF7F); +SDR 16 TDI (FFFF) TDO (FEFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFB); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (BBF7); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (6FFF); +SDR 16 TDI (FFFF) TDO (DFF7); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFBD); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FDFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFEA); +SDR 16 TDI (FFFF) TDO (75FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFDB); +SDR 16 TDI (FFFF) TDO (B5FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B6AF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (6BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7AF); +SDR 16 TDI (FFFF) TDO (FDFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (6BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BDAF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEA); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BBFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (4FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DEFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BAFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFBF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEE); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (A55F); +SDR 16 TDI (FFFF) TDO (FEBF); +SDR 16 TDI (FFFF) TDO (67C6); +SDR 16 TDI (FFFF) TDO (1EBF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (67FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (C2BF); +SDR 16 TDI (FFFF) TDO (47A6); +SDR 16 TDI (FFFF) TDO (1EBF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B55F); +SDR 16 TDI (FFFF) TDO (FE7F); +SDR 16 TDI (FFFF) TDO (67E6); +SDR 16 TDI (FFFF) TDO (1F3F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (67FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (C27F); +SDR 16 TDI (FFFF) TDO (47E6); +SDR 16 TDI (FFFF) TDO (1F3F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (3BB3); +SDR 16 TDI (FFFF) TDO (73EE); +SDR 16 TDI (FFFF) TDO (E6E7); +SDR 16 TDI (FFFF) TDO (B333); +SDR 16 TDI (FFFF) TDO (31F3); +SDR 16 TDI (FFFF) TDO (4666); +SDR 16 TDI (FFFF) TDO (7CCC); +SDR 16 TDI (FFFF) TDO (B98F); +SDR 16 TDI (FFFF) TDO (9999); +SDR 16 TDI (FFFF) TDO (73CC); +SDR 16 TDI (FFFF) TDO (CCC7); +SDR 16 TDI (FFFF) TDO (B999); +SDR 16 TDI (FFFF) TDO (99FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7337); +SDR 16 TDI (FFFF) TDO (4546); +SDR 16 TDI (FFFF) TDO (7677); +SDR 16 TDI (FFFF) TDO (B777); +SDR 16 TDI (FFFF) TDO (74AB); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (7DDD); +SDR 16 TDI (FFFF) TDO (BBA5); +SDR 16 TDI (FFFF) TDO (5DDD); +SDR 16 TDI (FFFF) TDO (7BDD); +SDR 16 TDI (FFFF) TDO (DDD2); +SDR 16 TDI (FFFF) TDO (B5DD); +SDR 16 TDI (FFFF) TDO (DDFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BF7F); +SDR 16 TDI (FFFF) TDO (FFF7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (8FFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (4FF7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FF7F); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9F7F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (77EE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (A55F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (A55F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFD); +SDR 16 TDI (FFFF) TDO (7BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AAFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BAFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEE); +SDR 16 TDI (FFFF) TDO (77FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (855F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (97FF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (4BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFDF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFE); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B55F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFF5); +SDR 16 TDI (FFFF) TDO (6BFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (3333); +SDR 16 TDI (FFFF) TDO (43E6); +SDR 16 TDI (FFFF) TDO (6667); +SDR 16 TDI (FFFF) TDO (B333); +SDR 16 TDI (FFFF) TDO (31F3); +SDR 16 TDI (FFFF) TDO (6666); +SDR 16 TDI (FFFF) TDO (7CCC); +SDR 16 TDI (FFFF) TDO (B98F); +SDR 16 TDI (FFFF) TDO (9999); +SDR 16 TDI (FFFF) TDO (73CC); +SDR 16 TDI (FFFF) TDO (CCC7); +SDR 16 TDI (FFFF) TDO (B999); +SDR 16 TDI (FFFF) TDO (99FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (6957); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (B777); +SDR 16 TDI (FFFF) TDO (74AB); +SDR 16 TDI (FFFF) TDO (7777); +SDR 16 TDI (FFFF) TDO (7DDD); +SDR 16 TDI (FFFF) TDO (BBA5); +SDR 16 TDI (FFFF) TDO (5DDD); +SDR 16 TDI (FFFF) TDO (7BDD); +SDR 16 TDI (FFFF) TDO (DDD2); +SDR 16 TDI (FFFF) TDO (B5DD); +SDR 16 TDI (FFFF) TDO (DDFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (B7FF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FEFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFF7); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (AFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7DFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFBF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFDF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FEF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFBD); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (BDFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (F7FF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF7); +SDR 16 TDI (FFFF) TDO (FDFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FF7E); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (DBFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (7FFD); +SDR 16 TDI (FFFF) TDO (DFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFB); +SDR 16 TDI (FFFF) TDO (77EF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFDD); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFEF); +SDR 16 TDI (FFFF) TDO (5FFD); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (BFEF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (EFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FEF1); +SDR 16 TDI (FFFF) TDO (67E7); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (9FED); +SDR 16 TDI (FFFF) TDO (EFFD); +SDR 16 TDI (FFFF) TDO (53FF); +SDR 16 TDI (FFFF) TDO (FFF9); +SDR 16 TDI (FFFF) TDO (B77F); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (B99F); +SDR 16 TDI (FFFF) TDO (BCCF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFC); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FF3); +SDR 16 TDI (FFFF) TDO (FFFE); +SDR 16 TDI (FFFF) TDO (AF9E); +SDR 16 TDI (FFFF) TDO (7CFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFE7); +SDR 16 TDI (FFFF) TDO (93E7); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5F3E); +SDR 16 TDI (FFFF) TDO (79F3); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (9FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (5FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (7FFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (BFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0001); +SIR 10 TDI (205); +RUNTEST 93 TCK; +SDR 16 TDI (FFFF) TDO (FFFF) MASK (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SDR 16 TDI (FFFF) TDO (FFFF); +SIR 10 TDI (203); +RUNTEST 93 TCK; +SDR 13 TDI (0000); +SIR 10 TDI (2F4); +RUNTEST 93 TCK; +SDR 16 TDI (7BFF); +RUNTEST 1800 TCK; +SDR 16 TDI (FFFF); +RUNTEST 1800 TCK; +SDR 16 TDI (BFFC); +RUNTEST 1800 TCK; +SDR 16 TDI (F9E7); +RUNTEST 1800 TCK; +SIR 10 TDI (201); +RUNTEST 18003 TCK; +SIR 10 TDI (3FF); +RUNTEST 18000 TCK; +STATE IDLE; From 6917ffe1e3b3258b5f81749b87e1e13f374f9217 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 11 Jul 2016 09:16:47 -0700 Subject: [PATCH 133/165] JTAG: Clean up definition of Target interface. --- firmware/common/jtag.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/common/jtag.hpp b/firmware/common/jtag.hpp index 67677f19..23154485 100644 --- a/firmware/common/jtag.hpp +++ b/firmware/common/jtag.hpp @@ -37,9 +37,9 @@ public: } virtual void delay(const size_t n) = 0; - virtual jtag::Target::bit_t clock( - const jtag::Target::bit_t tms_value, - const jtag::Target::bit_t tdi_value + virtual bit_t clock( + const bit_t tms_value, + const bit_t tdi_value ) = 0; }; From 18fe30136ea3c2e8d2498531d0ad3ace15a9a64f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 11 Jul 2016 09:39:02 -0700 Subject: [PATCH 134/165] JTAG: Move Target interface to separate header. --- firmware/common/jtag.hpp | 16 ++-------- firmware/common/jtag_target.hpp | 46 ++++++++++++++++++++++++++++ firmware/common/jtag_target_gpio.hpp | 2 +- 3 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 firmware/common/jtag_target.hpp diff --git a/firmware/common/jtag.hpp b/firmware/common/jtag.hpp index 23154485..57d258ac 100644 --- a/firmware/common/jtag.hpp +++ b/firmware/common/jtag.hpp @@ -22,6 +22,8 @@ #ifndef __JTAG_H__ #define __JTAG_H__ +#include "jtag_target.hpp" + #include #include @@ -29,20 +31,6 @@ namespace jtag { -class Target { -public: - using bit_t = uint_fast8_t; - - virtual ~Target() { - } - - virtual void delay(const size_t n) = 0; - virtual bit_t clock( - const bit_t tms_value, - const bit_t tdi_value - ) = 0; -}; - class JTAG { public: constexpr JTAG( diff --git a/firmware/common/jtag_target.hpp b/firmware/common/jtag_target.hpp new file mode 100644 index 00000000..455ae281 --- /dev/null +++ b/firmware/common/jtag_target.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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 __JTAG_TARGET_H__ +#define __JTAG_TARGET_H__ + +#include +#include + +namespace jtag { + +class Target { +public: + using bit_t = uint_fast8_t; + + virtual ~Target() { + } + + virtual void delay(const size_t n) = 0; + virtual bit_t clock( + const bit_t tms_value, + const bit_t tdi_value + ) = 0; +}; + +} /* namespace jtag */ + +#endif/*__JTAG_TARGET_H__*/ diff --git a/firmware/common/jtag_target_gpio.hpp b/firmware/common/jtag_target_gpio.hpp index 0b26a6f5..180f4d04 100644 --- a/firmware/common/jtag_target_gpio.hpp +++ b/firmware/common/jtag_target_gpio.hpp @@ -22,7 +22,7 @@ #ifndef __JTAG_TARGET_GPIO_H__ #define __JTAG_TARGET_GPIO_H__ -#include "jtag.hpp" +#include "jtag_target.hpp" #include From 22143c9543fdf3584a626d6a7f0349f44f6a5058 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 13 Jul 2016 11:02:13 -0700 Subject: [PATCH 135/165] JTAG: Remove unused methods. --- firmware/common/cpld_max5.hpp | 5 ----- firmware/common/jtag.hpp | 21 --------------------- 2 files changed, 26 deletions(-) diff --git a/firmware/common/cpld_max5.hpp b/firmware/common/cpld_max5.hpp index 6a206b64..98bf96d8 100644 --- a/firmware/common/cpld_max5.hpp +++ b/firmware/common/cpld_max5.hpp @@ -94,11 +94,6 @@ public: shift_ir(static_cast(instruction)); } - template - void shift_dr(std::bitset& bits) { - jtag.shift_dr(bits); - } - private: jtag::JTAG& jtag; diff --git a/firmware/common/jtag.hpp b/firmware/common/jtag.hpp index 57d258ac..d0f72035 100644 --- a/firmware/common/jtag.hpp +++ b/firmware/common/jtag.hpp @@ -90,27 +90,6 @@ public: return result; } - template - void shift_dr(std::bitset& bits) { - /* Run-Test/Idle -> Select-DR-Scan */ - target.clock(1, 0); - /* Scan -> Capture -> Shift */ - target.clock(0, 0); - target.clock(0, 0); - - for(size_t i=0; i Update */ - target.clock(1, 0); - /* Update -> Run-Test/Idle */ - target.clock(0, 0); - } - private: Target& target; From c0f4fbe32dc99c1d5d860b6030754b4539bc2281 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 16 Jul 2016 14:06:58 -0700 Subject: [PATCH 136/165] JTAG: Add GPIO definitions for HackRF CPLD. --- firmware/common/hackrf_gpio.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/firmware/common/hackrf_gpio.hpp b/firmware/common/hackrf_gpio.hpp index 0c99bf77..57257f06 100644 --- a/firmware/common/hackrf_gpio.hpp +++ b/firmware/common/hackrf_gpio.hpp @@ -78,6 +78,11 @@ constexpr std::array gpios_baseband_decimation { }; constexpr GPIO gpio_baseband_q_invert = gpio[GPIO0_13]; +constexpr GPIO gpio_cpld_tdo = gpio[GPIO5_18]; +constexpr GPIO gpio_cpld_tck = gpio[GPIO3_0]; +constexpr GPIO gpio_cpld_tms = gpio[GPIO3_4]; +constexpr GPIO gpio_cpld_tdi = gpio[GPIO3_1]; + /* LEDs */ constexpr LED led_usb { gpio_led_usb }; From 71c7f543c5b29112ba7598a4f59370d5f94e4bdb Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 15:44:30 -0700 Subject: [PATCH 137/165] JTAG: Add TAP state management. Not all that happy with the implementation, but it's doing the job for now. --- firmware/common/jtag_tap.cpp | 266 +++++++++++++++++++++++++++++++++++ firmware/common/jtag_tap.hpp | 155 ++++++++++++++++++++ 2 files changed, 421 insertions(+) create mode 100644 firmware/common/jtag_tap.cpp create mode 100644 firmware/common/jtag_tap.hpp diff --git a/firmware/common/jtag_tap.cpp b/firmware/common/jtag_tap.cpp new file mode 100644 index 00000000..57541b85 --- /dev/null +++ b/firmware/common/jtag_tap.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2016 Jared Boone, ShareBrained Technology, 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. + */ + +#include "jtag_tap.hpp" + +#include "utility.hpp" + +#include + +namespace jtag { +namespace tap { + +size_t bits_t::length() const { + return count; +} + +bits_t::operator bool() const { + return (count > 0); +} + +bool bits_t::operator[](const size_t index) const { + if( p && (index < count) ) { + const auto n = bytes() * 8 - index - 1; + const auto byte = n >> 3; + const auto bit = (n ^ 7) & 7; + return (p[byte] >> bit) & 1; + } else { + return default_value; + } +} + +size_t bits_t::bytes() const { + return (count + 7) >> 3; +} + +#if JTAG_TAP_DEBUG +static char nibble_to_hex_char(const uint8_t v) { + if( v < 0xa ) { + return 0x30 + v; + } else { + return 0x57 + v; + } +} + +std::string to_string(const bits_t& bits) { + std::string s { std::to_string(bits.length()) + "/0x" }; + for(size_t i=0; i> 4) & 0xf); + s += nibble_to_hex_char((bits.p[i] >> 0) & 0xf); + } + return s; +} +#endif + +namespace { + +using route_t = uint16_t; + +struct entry_t { + state_t tms[2]; + route_t route; +}; +static_assert(sizeof(entry_t) == 4, "Unexpected size of entry_t"); + +using table_t = std::array; +static_assert(sizeof(table_t) == (16 * 4), "Unexpected size of table_t"); + +const table_t table { { + { state_t::run_test_idle, state_t::test_logic_reset, 0b0000000000000001 }, // test_logic_reset test_logic_reset => 1, others => 0 + { state_t::run_test_idle, state_t::select_dr_scan, 0b1111111111111101 }, // run_test_idle run_test_idle => 0, others => 1 + { state_t::capture_dr, state_t::select_ir_scan, 0b1111111000000001 }, // select_dr_scan run_test_idle..update_dr => 0, others => 1 + { state_t::shift_dr, state_t::exit1_dr, 0b1111111111101111 }, // capture_dr shift_dr => 0, others => 1 + { state_t::shift_dr, state_t::exit1_dr, 0b1111111111101111 }, // shift_dr shift_dr => 0, others => 1 + { state_t::pause_dr, state_t::update_dr, 0b1111111100111111 }, // exit1_dr pause_dr, exit2_dr => 0, others => 1 + { state_t::pause_dr, state_t::exit2_dr, 0b1111111110111111 }, // pause_dr pause_dr => 0, others => 1 + { state_t::shift_dr, state_t::update_dr, 0b1111111111101111 }, // exit2_dr shift_dr => 0, others => 1 + { state_t::run_test_idle, state_t::select_dr_scan, 0b1111111111111101 }, // update_dr run_test_idle => 0, others => 1 + { state_t::capture_ir, state_t::test_logic_reset, 0b0000000000000001 }, // select_ir_scan test_logic_reset => 1, others => 0 + { state_t::shift_ir, state_t::exit1_ir, 0b1111011111111111 }, // capture_ir shift_ir => 0, others => 1 + { state_t::shift_ir, state_t::exit1_ir, 0b1111011111111111 }, // shift_ir shift_ir => 0, others => 1 + { state_t::pause_ir, state_t::update_ir, 0b1001111111111111 }, // exit1_ir pause_ir, exit2_ir => 0, others => 1 + { state_t::pause_ir, state_t::exit2_ir, 0b1101111111111111 }, // pause_ir pause_ir => 0, others => 1 + { state_t::shift_ir, state_t::update_ir, 0b1111011111111111 }, // exit2_ir shift_ir => 0, others => 1 + { state_t::run_test_idle, state_t::select_dr_scan, 0b1111111111111101 }, // update_ir run_test_idle => 0, others => 1 +} }; + +const std::array state_name { { + "test_logic_reset", + "run_test_idle", + "select_dr_scan", + "capture_dr", + "shift_dr", + "exit1_dr", + "pause_dr", + "exit2_dr", + "update_dr", + "select_ir_scan", + "capture_ir", + "shift_ir", + "exit1_ir", + "pause_ir", + "exit2_ir", + "update_ir", +} }; + +const std::array state_long_name { { + "Test-Logic-Reset", + "Run-Test/Idle", + "Select-DR-Scan", + "Capture-DR", + "Shift-DR", + "Exit1-DR", + "Pause-DR", + "Exit2-DR", + "Update-DR", + "Select-IR-Scan", + "Capture-IR", + "Shift-IR", + "Exit1-IR", + "Pause-IR", + "Exit2-IR", + "Update-IR", +} }; + +const entry_t& entry(const state_t state) { + return table[toUType(state)]; +} + +} /* namespace */ + +const char* c_str(const state_t state) { + return state_name[toUType(state)]; +} + +/* TAPState **************************************************************/ + +state_t TAPState::state() const { + return _state; +} + +void TAPState::advance(const bool tms) { + _state = entry(_state).tms[tms]; +} + +bool TAPState::advance_toward(const state_t desired_state) const { + return (entry(_state).route >> toUType(desired_state)) & 1; +} + +/* TAPMachine ************************************************************/ + +void TAPMachine::set_run_test(const uint32_t value) { + _run_test = value; +} + +void TAPMachine::set_repeat(const uint8_t value) { + _repeat = value; +} + +void TAPMachine::set_end_ir(const state_t state) { + _end_ir = state; +} + +void TAPMachine::set_end_dr(const state_t state) { + _end_dr = state; +} + +bool TAPMachine::shift_ir(const bits_t& tdi_value, const bits_t& tdo_expected, const bits_t& tdo_mask) { + return shift_data(tdi_value, tdo_expected, tdo_mask, state_t::shift_ir, _end_ir, _run_test); +} + +bool TAPMachine::shift_dr(const bits_t& tdi_value, const bits_t& tdo_expected, const bits_t& tdo_mask) { + return shift_data(tdi_value, tdo_expected, tdo_mask, state_t::shift_dr, _end_dr, _run_test); +} + +void TAPMachine::state(const state_t state) { + if( state == state_t::test_logic_reset ) { + for(int i=0; i<5; i++) { + clock(1); + } + } else { + advance_to_state(state); + } +} + +void TAPMachine::wait(const state_t wait_state, const state_t end_state, const uint32_t wait_time) { + advance_to_state(wait_state); + delay_us(wait_time); + advance_to_state(end_state); +} + +bool TAPMachine::clock(const bool tms, const bool tdi) { + tap.advance(tms); + return target.clock(tms, tdi); +} + +void TAPMachine::advance_to_state(const state_t desired_state) { + while( tap.state() != desired_state ) { + const auto tms = tap.advance_toward(desired_state); + clock(tms); + } +} + +void TAPMachine::delay_us(const uint32_t microseconds) { + target.delay(microseconds); +} + +void TAPMachine::shift_start(const state_t state) { + advance_to_state(state); +} + +bool TAPMachine::shift(const bits_t& tdi, const bits_t& tdo_expected, const bits_t& tdo_mask, const bool end_tms) { + if( tdo_expected.length() != tdo_mask.length() ) { + return false; + } + if( tdo_expected && (tdi.length() != tdo_expected.length()) ) { + return false; + } + + auto tdo_error = false; + for(uint32_t i=0; i +#include + +namespace jtag { +namespace tap { + +class bits_t { +public: + constexpr bits_t( + ) : p { nullptr }, + count { 0 } + { + } + + constexpr bits_t( + const size_t count, + const bool default_value = true + ) : p { nullptr }, + count { count }, + default_value { default_value } + { + } + + constexpr bits_t( + const uint8_t* const p, + const size_t count + ) : p { p }, + count { count } + { + } + + size_t length() const; + + explicit operator bool() const; + + bool operator[](const size_t index) const; + +private: + const uint8_t* p { nullptr }; + size_t count { 0 }; + bool default_value { false }; + + size_t bytes() const; +}; + +enum class state_t : uint8_t { + /* Ordinal values are important for "routes" values, and to match XSVF definitions. */ + test_logic_reset = 0, + run_test_idle = 1, + select_dr_scan = 2, + capture_dr = 3, + shift_dr = 4, + exit1_dr = 5, + pause_dr = 6, + exit2_dr = 7, + update_dr = 8, + select_ir_scan = 9, + capture_ir = 10, + shift_ir = 11, + exit1_ir = 12, + pause_ir = 13, + exit2_ir = 14, + update_ir = 15, +}; + +class TAPState { +public: + constexpr TAPState( + ) : _state { state_t::test_logic_reset } + { + } + + state_t state() const; + void advance(const bool tms); + bool advance_toward(const state_t desired_state) const; + +private: + state_t _state; +}; + +class TAPMachine { +public: + constexpr TAPMachine( + jtag::Target& target + ) : target { target } + { + } + + void set_run_test(const uint32_t value); + void set_repeat(const uint8_t value); + void set_end_ir(const state_t state); + void set_end_dr(const state_t state); + + bool shift(const bits_t& tdi, const bool end_tms) { + return shift(tdi, {}, {}, end_tms); + } + + bool shift(const bits_t& tdi, const bits_t& tdo_expected, const bits_t& tdo_mask, const bool end_tms); + + bool shift_ir(const bits_t& tdi_value, const bits_t& tdo_expected = {}, const bits_t& tdo_mask = {}); + bool shift_dr(const bits_t& tdi_value, const bits_t& tdo_expected = {}, const bits_t& tdo_mask = {}); + + void state(const state_t state); + + void wait(const state_t wait_state, const state_t end_state, const uint32_t wait_time); + +private: + jtag::Target& target; + TAPState tap { }; + + uint32_t _run_test { 0 }; + uint8_t _repeat { 0 }; + state_t _end_ir { }; + state_t _end_dr { }; + + bool clock(const bool tms, const bool tdi=false); + void advance_to_state(const state_t desired_state); + void delay_us(const uint32_t microseconds); + + void shift_start(const state_t state); + void shift_end(const state_t end_state, const uint32_t end_delay); + + bool shift_data(const bits_t& tdi, const bits_t& tdo_expected, const bits_t& tdo_mask, const state_t state, const state_t end_state, const uint32_t end_delay); +}; + +} /* namespace tap */ +} /* namespace jtag */ + +#endif/*__JTAG_TAP_H__*/ From 4cc356f32594ff33e6edb9d569571665f1ba0c3d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 15:45:00 -0700 Subject: [PATCH 138/165] JTAG: Code to manage HackRF CPLD interactions. --- firmware/common/cpld_xilinx.cpp | 145 ++++++++++++++++++++++++++++++++ firmware/common/cpld_xilinx.hpp | 122 +++++++++++++++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 firmware/common/cpld_xilinx.cpp create mode 100644 firmware/common/cpld_xilinx.hpp diff --git a/firmware/common/cpld_xilinx.cpp b/firmware/common/cpld_xilinx.cpp new file mode 100644 index 00000000..7cc6b79d --- /dev/null +++ b/firmware/common/cpld_xilinx.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2016 Jared Boone, ShareBrained Technology, 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. + */ + +#include "cpld_xilinx.hpp" + +namespace cpld { +namespace xilinx { + +void XC2C64A::write_sram(const verify_blocks_t& blocks) { + tap.set_repeat(0); + tap.set_end_ir(state_t::run_test_idle); + tap.set_end_dr(state_t::run_test_idle); + + reset(); + enable(); + + shift_ir(instruction_t::ISC_WRITE); + for(const auto& block : blocks) { + tap.state(state_t::shift_dr); + tap.shift({ block.data.data(), block_length }, false); + tap.shift({ &block.id, block_id_length }, true); + tap.state(state_t::run_test_idle); + } + + disable(); + bypass(); + + tap.state(state_t::test_logic_reset); +} + +bool XC2C64A::verify_sram(const verify_blocks_t& blocks) { + tap.set_repeat(0); + tap.set_end_ir(state_t::run_test_idle); + tap.set_end_dr(state_t::run_test_idle); + + reset(); + enable(); + + shift_ir(instruction_t::ISC_SRAM_READ); + + // Prime the operation with a read of an empty row. + const jtag::tap::bits_t empty_row { block_length }; + + tap.state(state_t::shift_dr); + tap.shift(empty_row, false); + + auto error = false; + for(const auto& block : blocks) { + tap.shift({ &block.id, block_id_length }, true); + tap.state(state_t::run_test_idle); + + tap.state(state_t::shift_dr); + error |= tap.shift(empty_row, { block.data.data(), block_length }, { block.mask.data(), block_length }, false); + } + // Redundant operation to finish the row. + tap.shift({ &blocks[0].id, block_id_length }, true); + tap.state(state_t::run_test_idle); + tap.set_end_dr(state_t::run_test_idle); + + disable(); + bypass(); + + tap.state(state_t::test_logic_reset); + + return !error; +} + +bool XC2C64A::verify_eeprom(const verify_blocks_t& blocks) { + tap.set_repeat(0); + tap.set_end_ir(state_t::run_test_idle); + tap.set_end_dr(state_t::run_test_idle); + + reset(); + bypass(); + enable(); + + shift_ir(instruction_t::ISC_READ); + + const jtag::tap::bits_t empty_row { block_length }; + + auto error = false; + for(const auto& block : blocks) { + tap.set_end_dr(state_t::pause_dr); + tap.shift_dr({ &block.id, block_id_length }); + tap.set_end_ir(state_t::run_test_idle); + tap.wait(state_t::pause_dr, state_t::pause_dr, 20); + tap.set_end_ir(state_t::run_test_idle); + tap.wait(state_t::run_test_idle, state_t::run_test_idle, 100); + error |= tap.shift_dr(empty_row, { block.data.data(), block_length }, { block.mask.data(), block_length }); + tap.wait(state_t::run_test_idle, state_t::run_test_idle, 100); + } + + disable(); + bypass(); + + tap.state(state_t::test_logic_reset); + + return !error; +} + +bool XC2C64A::shift_ir(const instruction_t instruction) { + const ir_t ir_buffer = toUType(instruction); + const jtag::tap::bits_t bits { &ir_buffer, ir_length }; + return tap.shift_ir(bits); +} + +void XC2C64A::reset() { + tap.state(state_t::test_logic_reset); + tap.state(state_t::run_test_idle); +} + +void XC2C64A::enable() { + shift_ir(instruction_t::ISC_ENABLE); + tap.wait(state_t::run_test_idle, state_t::run_test_idle, 800); +} + +void XC2C64A::disable() { + shift_ir(instruction_t::ISC_DISABLE); + tap.wait(state_t::run_test_idle, state_t::run_test_idle, 100); +} + +bool XC2C64A::bypass() { + return shift_ir(instruction_t::BYPASS); +} + +} /* namespace xilinx */ +} /* namespace cpld */ diff --git a/firmware/common/cpld_xilinx.hpp b/firmware/common/cpld_xilinx.hpp new file mode 100644 index 00000000..36f7476a --- /dev/null +++ b/firmware/common/cpld_xilinx.hpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2016 Jared Boone, ShareBrained Technology, 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 __CPLD_XILINX_H__ +#define __CPLD_XILINX_H__ + +#include "jtag_tap.hpp" + +#include "utility.hpp" + +#include +#include +#include + +namespace cpld { +namespace xilinx { + +using jtag::tap::state_t; + +class XC2C64A { +public: + using block_id_t = uint8_t; + + static constexpr size_t block_length = 274; + static constexpr size_t blocks_count = 98; + + static constexpr size_t block_bytes = (block_length + 7) >> 3; + + struct verify_block_t { + block_id_t id; + std::array data; + std::array mask; + }; + + struct program_block_t { + block_id_t id; + std::array data; + }; + + using verify_blocks_t = std::array; + + constexpr XC2C64A( + jtag::Target& jtag_interface + ) : tap { jtag_interface } + { + } + + void write_sram(const verify_blocks_t& blocks); + bool verify_sram(const verify_blocks_t& blocks); + + bool verify_eeprom(const verify_blocks_t& blocks); + +private: + static constexpr size_t idcode_length = 32; + using idcode_t = uint32_t; + + static constexpr size_t ir_length = 8; + static constexpr size_t block_id_length = 7; + + static constexpr idcode_t idcode = 0x06e58093; + static constexpr idcode_t idcode_mask = 0x0fff8fff; + + using ir_t = uint8_t; + + jtag::tap::TAPMachine tap; + + enum class instruction_t : ir_t { + INTEST = 0b00000010, // -> boundary-scan + BYPASS = 0b11111111, // -> bypass + SAMPLE = 0b00000011, // -> boundary-scan + EXTEST = 0b00000000, // -> boundary-scan + IDCODE = 0b00000001, // -> device ID + USERCODE = 0b11111101, // -> device ID + HIGHZ = 0b11111100, // -> bypass + ISC_ENABLE_CLAMP = 0b11101001, // -> ISC shift + ISC_ENABLE_OTF = 0b11100100, // -> ISC shift + ISC_ENABLE = 0b11101000, // -> ISC shift + ISC_SRAM_READ = 0b11100111, // -> ISC shift + ISC_WRITE = 0b11100110, // -> ISC shift, alias ISC_SRAM_WRITE + ISC_ERASE = 0b11101101, // -> ISC shift + ISC_PROGRAM = 0b11101010, // -> ISC shift + ISC_READ = 0b11101110, // -> ISC shift, alias ISC_VERIFY + ISC_INIT = 0b11110000, // -> ISC shift + ISC_DISABLE = 0b11000000, // -> ISC shift + TEST_ENABLE = 0b00010001, // alias Private1 + BULKPROG = 0b00010010, // alias Private2 + ERASE_ALL = 0b00010100, // alias Private4 + MVERIFY = 0b00010011, // alias Private3 + TEST_DISABLE = 0b00010101, // alias Private5 + ISC_NOOP = 0b11100000, // -> bypass + }; + + bool shift_ir(const instruction_t instruction); + + void reset(); + void enable(); + void disable(); + bool bypass(); +}; + +} /* namespace xilinx */ +} /* namespace cpld */ + +#endif/*__CPLD_XILINX_H__*/ From 51c114405b7fdbfcfe7eb90a4346cced7c295cff Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 15:46:12 -0700 Subject: [PATCH 139/165] JTAG: Tool that generates C++ files from XC2C64A SVF data. --- firmware/tools/extract_svf_data_xc2c64a.py | 341 +++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100755 firmware/tools/extract_svf_data_xc2c64a.py diff --git a/firmware/tools/extract_svf_data_xc2c64a.py b/firmware/tools/extract_svf_data_xc2c64a.py new file mode 100755 index 00000000..ee504c3c --- /dev/null +++ b/firmware/tools/extract_svf_data_xc2c64a.py @@ -0,0 +1,341 @@ +#!/usr/bin/env python + +# +# Copyright (C) 2016 Jared Boone, ShareBrained Technology, 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. +# + +# Very fragile code to extract data from Xilinx XC2C64A CPLD SVF + +import sys +import re +import os.path +import argparse + +def crack_variable_path(variable_path): + tmp = args.variable_path.split('::') + namespaces, variable_name = tmp[:-1], tmp[-1] + return namespaces, variable_name + +parser = argparse.ArgumentParser() +parser.add_argument('input_file_path', type=str) +parser.add_argument('variable_path', type=str) +parser.add_argument('header_file_path', type=str) +parser.add_argument('data_file_path', type=str) +args = parser.parse_args() + +f = open(args.input_file_path, 'r') +namespaces, variable_name = crack_variable_path(args.variable_path) + +def to_hex(value, length_bits): + return hex(value)[2:].zfill((length_bits + 3) >> 2) + +def long_int_to_bytes(n, bit_count): + byte_count = (bit_count + 7) >> 3 + h = hex(n)[2:].zfill(byte_count * 2) + return [int(h[n:n+2], 16) for n in range(0, len(h), 2)] + +re_sdr = re.compile(r'^(?P\d+)\s*TDI\s*\((?P[0-9A-F]+)\)(|\s*SMASK\s*\((?P[0-9A-F]+)\))(|\s*TDO\s*\((?P[0-9A-F]+)\))(|\s*MASK\s*\((?P[0-9A-F]+)\))\s*;$') +re_sir = re_sdr + +class SIR_or_SDR(object): + def __init__(self, name, s): + self.name = name + match = re_sdr.match(s) + self.length = int(match.group('length')) + self.tdi = self._bits(match.group('tdi')) + self.smask = self._optional_bits(match.group('smask')) + self.tdo = self._optional_bits(match.group('tdo')) + self.mask = self._optional_bits(match.group('mask')) + + def __repr__(self): + result = [self.name, str(self.length)] + result.append('TDI (%s)' % to_hex(self.tdi, self.length)) + if self.smask: + result.append('SMASK (%s)' % to_hex(self.smask, self.length)) + if self.tdo: + result.append('TDO (%s)' % to_hex(self.tdo, self.length)) + if self.mask: + result.append('MASK (%s)' % to_hex(self.mask, self.length)) + result.append(';') + return ' '.join(result) + + def _bits(self, matched): + return int(matched, 16) + + def _optional_bits(self, matched): + return self._bits(matched) if matched else None + +class SDR(SIR_or_SDR): + def __init__(self, s): + SIR_or_SDR.__init__(self, 'SDR', s) + +class SIR(SIR_or_SDR): + def __init__(self, s): + SIR_or_SDR.__init__(self, 'SIR', s) + +class SVFParser(object): + instruction_parsers = { + 'SIR': SIR, + 'SDR': SDR, + } + + def parse(self, f, instruction_handler_map): + complete_line = '' + for line in f: + line = line.strip().upper() + if line.startswith('//'): + continue + + complete_line += line + if not line.endswith(';'): + continue + + instruction_name, args_string = complete_line.split(None, 1) + instruction = self.instruction_parser(instruction_name, args_string) + if instruction: + instruction_type = type(instruction) + if instruction_type in instruction_handler_map: + instruction_handler_map[instruction_type](instruction) + + if complete_line.endswith(';'): + complete_line = '' + + def instruction_parser(self, instruction_name, args_string): + if instruction_name in self.instruction_parsers: + parser = self.instruction_parsers[instruction_name] + return parser(args_string) + else: + return None + +class ProgramExtractor(object): + idcode = int('0bXXXX0110111001011XXX000010010011'.replace('X', '0'), 2) + idcode_mask = None + id_bits = 7 + block_bits = 274 + block_ordinals = frozenset(list(range(64)) + list(range(80, 82)) + list(range(96, 128))) + block_count = len(block_ordinals) + + def __init__(self): + self.tap_instruction = None + self.program_data = [] + self.verify_data = [] + self.sdr_smask = None + self.sdr_mask = None + + def map(self): + return { + SIR: self.on_sir, + SDR: self.on_sdr, + } + + def on_sir(self, o): + assert(o.length == 8) + + if o.tdi == 0x01: + self.tap_instruction = 'idcode' + elif o.tdi == 0xea: + self.tap_instruction = 'program' + self.program_data.append([]) + elif o.tdi == 0xee: + self.tap_instruction = 'verify' + self.verify_data.append([]) + self.verify_block_id = None + else: + self.tap_instruction = None + + def on_sdr(self, o): + if o.smask: + self.sdr_smask = o.smask + if o.mask: + self.sdr_mask = o.mask + + if self.tap_instruction == 'idcode': + assert(o.length == 32) + assert(self.sdr_smask == 0xffffffff) + assert((o.tdo & self.sdr_mask) == self.idcode) + if self.idcode_mask is None: + self.idcode_mask = self.sdr_mask + else: + assert(self.idcode_mask == self.sdr_mask) + + elif self.tap_instruction == 'program': + assert(o.length == (self.id_bits + self.block_bits)) + assert(self.sdr_smask == ((1 << o.length) - 1)) + assert(o.tdo is None) + assert(o.mask is None) + block_id = o.tdi >> (o.length - 7) + mask = (1 << (o.length - 7)) - 1 + self.program_data[-1].append({ + 'id': block_id, + 'tdi': o.tdi & mask, + 'length': o.length - 7, + }) + elif self.tap_instruction == 'verify': + assert(o.length in (self.id_bits, self.block_bits)) + + if o.length == self.id_bits: + assert(o.smask == ((1 << self.id_bits) - 1)) + assert(o.tdo is None) + assert(o.mask is None) + self.verify_block_id = o.tdi + + elif o.length == self.block_bits: + assert(o.tdi == (1 << o.length) - 1) + assert(o.smask == (1 << o.length) - 1) + self.verify_data[-1].append({ + 'id': self.verify_block_id, + 'tdo': o.tdo, + 'mask': o.mask, + 'length': o.length, + }) + self.verify_block_id = None + +program_extractor = ProgramExtractor() + +parser = SVFParser() +parser.parse(f, program_extractor.map()) + +def has_all_blocks(blocks): + ordinals = set() + + for block in blocks: + ordinal = int(bin(block['id'])[2:].zfill(7)[::-1], 2) + ordinals.add(ordinal) + + return ordinals == program_extractor.block_ordinals + +def is_verify_blank(blocks): + for block in blocks: + length = block['length'] + mask = (1 << length) - 1 + if block['tdo'] != mask: + return False + if block['mask'] != mask: + return False + return True + +def deduplicate(passes): + result = [passes[0]] + for this_pass in passes[1:]: + if this_pass != result[0]: + result.append(this_pass) + return result + +def program_and_verify_match(program, verify): + for program_block, verify_block in zip(program, verify): + if program_block['tdi'] != verify_block['tdo']: + return False + return True + +program_passes = [blocks for blocks in program_extractor.program_data if has_all_blocks(blocks)] +program_done = [blocks for blocks in program_extractor.program_data if len(blocks) == 1][0] +if len(program_passes) == 0: + raise RuntimeError('no complete program passes') +if len(program_passes) > 1: + raise RuntimeError('too many program passes') +program = program_passes[0] + +verify_passes = [blocks for blocks in program_extractor.verify_data if has_all_blocks(blocks) and not is_verify_blank(blocks)] +verify_passes = deduplicate(verify_passes) +if len(verify_passes) == 0: + raise RuntimeError('no complete verify passes') +if len(verify_passes) > 1: + raise RuntimeError('too many verify passes') +verify = verify_passes[0] + +if not program_and_verify_match(program, verify): + raise RuntimeError('program and verify data do not match') + +class FileGen(object): + def comment_header(self): + return ['/*' , ' * WARNING: Auto-generated file. Do not edit.', '*/'] + + def includes(self, filenames): + return ['#include "%s"' % filename for filename in filenames] + + def _namespaces(self, ns_list, line_format): + return [line_format % ns for ns in ns_list] + + def namespaces_start(self, ns_list): + return self._namespaces(ns_list, 'namespace %s {') + + def namespaces_end(self, ns_list): + return self._namespaces(ns_list, '} /* namespace %s */') + + def verify_block(self, block): + tdo_bytes = long_int_to_bytes(block['tdo'], block['length']) + mask_bytes = long_int_to_bytes(block['mask'], block['length']) + tdo_cpp_s = ', '.join(['0x%02x' % b for b in tdo_bytes]); + mask_cpp_s = ', '.join(['0x%02x' % b for b in mask_bytes]); + return '\t{ 0x%02x, { { %s } }, { { %s } } },' % (block['id'], tdo_cpp_s, mask_cpp_s) + + def verify_blocks_declaration(self, type_name, variable_name): + return ['extern const %s %s;' % (type_name, variable_name)] + + def verify_blocks_definition(self, type_name, variable_name, blocks): + return ['const %s %s { {' % (type_name, variable_name)] \ + + [self.verify_block(block) for block in blocks] \ + + ['} };'] + + # def cpp_program_t(block): + # tdi_bytes = long_int_to_bytes(block['tdi'], block['length']) + # tdi_cpp_s = ', '.join(['0x%02x' % b for b in tdi_bytes]); + # return '0x%02x, { { %s } }' % (block['id'], tdi_cpp_s) + + def __repr__(self): + return '\n'.join(self.lines) + + def to_file(self, file_path): + f = open(file_path, 'w') + f.write(str(self)) + f.close() + +class HeaderGen(FileGen): + def __init__(self, includes, namespaces, type_name, variable_name): + self.lines = self.comment_header() \ + + self.includes(includes) \ + + self.namespaces_start(namespaces) \ + + self.verify_blocks_declaration(type_name, variable_name) \ + + self.namespaces_end(namespaces) \ + + [''] + +class DataGen(FileGen): + def __init__(self, includes, namespaces, type_name, variable_name, verify_blocks): + self.lines = self.comment_header() \ + + self.includes(includes) \ + + self.namespaces_start(namespaces) \ + + self.verify_blocks_definition(type_name, variable_name, verify_blocks) \ + + self.namespaces_end(namespaces) \ + + [''] + +# Tricky (a.k.a. "brittle") code to set DONE bit +for block in verify: + if block['id'] == 0x05: + block['tdo'] = program_done[0]['tdi'] + +header_file_name = os.path.split(args.header_file_path)[1] + +header_includes = ('cpld_xilinx.hpp',) +data_includes = (header_file_name,) + +type_name = '::cpld::xilinx::XC2C64A::verify_blocks_t' + +HeaderGen(header_includes, namespaces, type_name, variable_name).to_file(args.header_file_path) +DataGen(data_includes, namespaces, type_name, variable_name, verify).to_file(args.data_file_path) From cd3a91b3afec90615c3da716cf0daf6ab207dbde Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 15:48:02 -0700 Subject: [PATCH 140/165] JTAG: HackRF CPLD SVF file for embedding in firmware. --- firmware/hackrf_cpld_default.svf | 1144 ++++++++++++++++++++++++++++++ 1 file changed, 1144 insertions(+) create mode 100644 firmware/hackrf_cpld_default.svf diff --git a/firmware/hackrf_cpld_default.svf b/firmware/hackrf_cpld_default.svf new file mode 100644 index 00000000..d35ff4b1 --- /dev/null +++ b/firmware/hackrf_cpld_default.svf @@ -0,0 +1,1144 @@ +// Created using Xilinx Cse Software [ISE - 14.7] +// Date: Fri Jul 15 12:29:50 2016 + +TRST OFF; +ENDIR IDLE; +ENDDR IDLE; +STATE RESET; +STATE IDLE; +FREQUENCY 1E6 HZ; +//Operation: Program -p 0 -e -v +TIR 0 ; +HIR 0 ; +TDR 0 ; +HDR 0 ; +TIR 0 ; +HIR 0 ; +HDR 0 ; +TDR 0 ; +//Loading device with 'idcode' instruction. +SIR 8 TDI (01) SMASK (ff) ; +SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6e5f093) MASK (0fff8fff) ; +//Check for Read/Write Protect. +SIR 8 TDI (ff) TDO (01) MASK (03) ; +//Boundary Scan Chain Contents +//Position 1: xc2c64a +TIR 0 ; +HIR 0 ; +TDR 0 ; +HDR 0 ; +TIR 0 ; +HIR 0 ; +TDR 0 ; +HDR 0 ; +TIR 0 ; +HIR 0 ; +HDR 0 ; +TDR 0 ; +//Loading device with 'idcode' instruction. +SIR 8 TDI (01) ; +SDR 32 TDI (00000000) TDO (f6e5f093) ; +//Check for Read/Write Protect. +SIR 8 TDI (ff) TDO (01) MASK (03) ; +TIR 0 ; +HIR 0 ; +HDR 0 ; +TDR 0 ; +// Loading devices with 'enable' or 'bypass' instruction. +SIR 8 TDI (e8) ; +// Loading devices with 'erase' or 'bypass' instruction. +ENDIR IRPAUSE; +SIR 8 TDI (ed) SMASK (ff) ; +ENDIR IDLE; +STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRPAUSE; +RUNTEST DRPAUSE 20 TCK; +STATE IDLE; +RUNTEST IDLE 100000 TCK; +STATE DRPAUSE; +RUNTEST DRPAUSE 5000 TCK; +RUNTEST IDLE 1 TCK; +// Loading devices with 'init' or 'bypass' instruction. +ENDIR IRPAUSE; +SIR 8 TDI (f0) SMASK (ff) ; +STATE IDLE; +RUNTEST IDLE 20 TCK; +// Loading devices with 'init' or 'bypass' instruction. +ENDIR IRPAUSE; +SIR 8 TDI (f0) SMASK (ff) ; +STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; +RUNTEST 800 TCK; +ENDIR IDLE; +// Loading devices with 'conld' or 'bypass' instruction. +SIR 8 TDI (c0) ; +RUNTEST 100 TCK; +// Loading devices with 'conld' or 'bypass' instruction. +SIR 8 TDI (c0) ; +RUNTEST 100 TCK; +// Loading devices with 'enable' or 'bypass' instruction. +SIR 8 TDI (e8) ; +// Programming. +// Loading devices with 'program' instruction. +ENDIR IRPAUSE; +SIR 8 TDI (ea) ; +SDR 281 TDI (0003c1fff37ffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe0f) SMASK (01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +ENDIR IDLE; +RUNTEST 10000 TCK; +SDR 281 TDI (0103f9d37f777ffffffffffffffffffffffdde6efffffffffffffffffffffff3fffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0180f93dbfd53fffffffffffffffefffffe9de7fffffffffffffffffffffffff3ffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0083c1ffffffffffffffffffffffffffffffff777efbfffffffffffffffffeeeeeeeee0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00c3f9fffffffffffffffffffffffffffffddf7ffffffffffffffffffffffffff3fffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01c0f9ffffffd7fffffffffffffffffffff99e7fffffffffffffffffffffffbbbbbbba7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0143c1ff7f52fffffffffffffffffffffffffeeefffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0043f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0060f9edf3777ffffffffffffffffffffffdde6effffffffffffffffffffffbbbbbbba7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0163c1fffffffffffffffffffffffffffffddf7ffffffffffffffffffffffffffff3fe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01e3f9fffffffffffffffffffffffffffffd7f7fffffffffffffffffffffffffffff3e7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00e0f96bf5dcfffffffffffffffffffffffafefffffffffffffffffffffffffffffffe03) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00a3c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01a3f97f7ffffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0120f9fffffffffffffffffffffffffffffd7f7fffffffffffffffffffffff3fffffff83) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0023c1fffffffffffffffffffffffffffff5ff7fffffffffffffffffffffffbbbbbbba4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0033f9fffffffffffffffffffffffffffffd7f7ffffffffffffffffffffffffffffff27c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0130f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01b3c1ffffffefffffffffffffffeffffffbbefffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00b3f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00f0f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01f3c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffebffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0173f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffff4bffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0070f9ffffffffffffffffffffffffffffffe587fffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0053c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5fffe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0153f9ffffffd7ffffffffffffffffffffffffffffffffffffffffffffffffffff4bfe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01d0f9ffffd57fffffffffffffffffffffffffffffffffffffffffffffffffffffff4b83) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00d3c1552afffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0093f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0190f9ffffadfffffffffffffffffffffff8de7fffffffffffffffffffffffffff3ffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0113c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0013f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0018f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) ; +RUNTEST 10000 TCK; +SDR 281 TDI (011bc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (019b99fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (009af9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00dbc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01db99fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (015afdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) ; +RUNTEST 10000 TCK; +SDR 281 TDI (005bc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (007bddfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0178f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01fbc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00fbddfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00b8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01bbc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (013bd9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0038f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03) ; +RUNTEST 10000 TCK; +SDR 281 TDI (002bc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0128d9dffffffffffffffffffffffffffffffeeefffffffffffffffffffffffffffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01ab0133ffffffffffffffffffffffffffebfefffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00abc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00eae1ffffcffffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01e8f92dfbfffffffffffffffffffffffffbbefffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (016bc9dffffffffffffffffffffffffffffffeeefffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0068e1f5fffffffffffffffffffffffffffffefebffffffffffffffffffffffffffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (004bc7dffffffffffffffffffffffffffffffeeefffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (014bc1ff3ffffffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01cae1ff36ccccccfffffffffffffffffffffeeefffffffffffffffffffffffffffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00c8f9ffffffcffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (008bc9fffffcfffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0188e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (010bc7fff6fffffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (000bc1ffffffffcffffffffffffffffffffbbefffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (000ee1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (010cf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (018fc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (008ce1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00cfc6abfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01cfc1febffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (014ee1ffeefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; +RUNTEST 10000 TCK; +SDR 281 TDI (004cf9fffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (006fc9ffffad7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (016ce1fffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01efc7ffffffd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00efc9fffffffad7fffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00ace1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01afc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (012fc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (002ee1fffffffcfffffffffffffffffffffbbefffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (003cf9fffffffffb7ffffffffffffffffffbbefffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (013fc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01bee1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00bcf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00ffc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01fff9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (017cf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (007fc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (005ce0bffffffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (015fc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (01dfc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (00dce1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (009fc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (019fc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (011ce1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; +RUNTEST 10000 TCK; +SDR 281 TDI (001fc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 10000 TCK; +SDR 281 TDI (0117ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 10000 TCK; +// Loading devices with 'init' or 'bypass' instruction. +ENDIR IRPAUSE; +SIR 8 TDI (f0) SMASK (ff) ; +STATE IDLE; +RUNTEST IDLE 20 TCK; +// Loading devices with 'init' or 'bypass' instruction. +ENDIR IRPAUSE; +SIR 8 TDI (f0) SMASK (ff) ; +STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; +RUNTEST 800 TCK; +ENDIR IDLE; +// Loading devices with 'conld' or 'bypass' instruction. +SIR 8 TDI (c0) ; +RUNTEST 100 TCK; +// Loading devices with 'conld' or 'bypass' instruction. +SIR 8 TDI (c0) ; +RUNTEST 100 TCK; +TIR 0 ; +HIR 0 ; +HDR 0 ; +TDR 0 ; +//Loading device with 'enable' instruction. +SIR 8 TDI (e8) ; +//Loading device with 'enable' instruction. +SIR 8 TDI (e8) ; +// Verification. +// Loading device with a 'verify' instruction. +ENDIR IRPAUSE; +SIR 8 TDI (ee) ; +ENDDR DRPAUSE; +SDR 7 TDI (00) SMASK (7f) ; +ENDIR IDLE; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fff37ffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (40) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9d37f777ffffffffffffffffffffffdde6efffffffffffffffffffffff3fffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (60) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f93dbfd53fffffffffffffffefffffe9de7fffffffffffffffffffffffff3ffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (20) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ffffffffffffffffffffffffffffffff777efbfffffffffffffffffeeeeeeeee0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (30) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffddf7ffffffffffffffffffffffffff3fffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (70) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffd7fffffffffffffffffffff99e7fffffffffffffffffffffffbbbbbbba7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (50) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ff7f52fffffffffffffffffffffffffeeefffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (10) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (18) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9edf3777ffffffffffffffffffffffdde6effffffffffffffffffffffbbbbbbba7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (58) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffddf7ffffffffffffffffffffffffffff3fe4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (78) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffd7f7fffffffffffffffffffffffffffff3e7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (38) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f96bf5dcfffffffffffffffffffffffafefffffffffffffffffffffffffffffffe03) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (28) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (68) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f97f7ffffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (48) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffd7f7fffffffffffffffffffffff3fffffff83) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (08) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffff5ff7fffffffffffffffffffffffbbbbbbba4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (0c) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffd7f7ffffffffffffffffffffffffffffff27c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (4c) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (6c) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ffffffefffffffffffffffeffffffbbefffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (2c) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (3c) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (7c) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffebffffffe0f) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (5c) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffff4bffffe1d) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (1c) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffffffffffffffffffffffffffe587fffffffffffffffffffffffffffffe7c) MASK ( +03fffffffffffffffffffffffffffffe001ff801ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (14) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5fffe4f) MASK ( +03fffffffffffffffffffffffffffffe001f8001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (54) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9ffffffd7ffffffffffffffffffffffffffffffffffffffffffffffffffff4bfe7c) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (74) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffd57fffffffffffffffffffffffffffffffffffffffffffffffffffffff4b83) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (34) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1552afffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (24) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (64) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffadfffffffffffffffffffffff8de7fffffffffffffffffffffffffff3ffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (44) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (04) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (06) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (46) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (66) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0399fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (26) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (36) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (76) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0399fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (56) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02fdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (16) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (1e) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03ddfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (5e) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (7e) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (3e) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03ddfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (2e) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (6e) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (4e) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03d9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (0e) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (0a) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (4a) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00d9dffffffffffffffffffffffffffffffeeefffffffffffffffffffffffffffffe1d) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (6a) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (030133ffffffffffffffffffffffffffebfefffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (2a) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (3a) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1ffffcffffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe1d) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (7a) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f92dfbfffffffffffffffffffffffffbbefffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (5a) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9dffffffffffffffffffffffffffffffeeefffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (1a) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1f5fffffffffffffffffffffffffffffefebffffffffffffffffffffffffffffe1d) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (12) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c7dffffffffffffffffffffffffffffffeeefffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (52) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ff3ffffffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (72) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1ff36ccccccfffffffffffffffffffffeeefffffffffffffffffffffffffffffe1d) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (32) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffcffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (22) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffcfffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (62) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (42) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c7fff6fffffffffffffffffffffffffbeefffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (02) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ffffffffcffffffffffffffffffffbbefffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (03) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (43) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (63) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (23) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (33) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c6abfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (73) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1febffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (53) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1ffeefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (13) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (1b) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9ffffad7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (5b) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffe7f) MASK ( +03fffffffffffffffffffffffffffffe00078001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (7b) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c7ffffffd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (3b) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffad7fffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (2b) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (6b) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (4b) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (0b) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1fffffffcfffffffffffffffffffffbbefffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (0f) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffb7ffffffffffffffffffbbefffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (4f) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (6f) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (2f) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (3f) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (7f) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (5f) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (1f) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (17) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e0bffffffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (57) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (77) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (37) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (27) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (67) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (47) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (07) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( +03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (05) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) MASK ( +0000000000000000000000000000000000000000000000000000000000000000000000) ; +RUNTEST 100 TCK; +ENDDR DRPAUSE; +SDR 7 TDI (45) SMASK (7f) ; +RUNTEST DRPAUSE 20 TCK; +ENDDR IDLE; +RUNTEST IDLE 100 TCK; +// masking lower UES bits. +SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) MASK ( +0000000000000000000000000000000000000000000000000000000000000000000000) ; +RUNTEST 100 TCK; +SIR 8 TDI (f0) SMASK (ff) ; +STATE IDLE; +RUNTEST IDLE 20 TCK; +ENDIR IRPAUSE; +SIR 8 TDI (f0) SMASK (ff) ; +STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; +RUNTEST 800 TCK; +ENDIR IDLE; +//Loading device with 'conld' instruction. +SIR 8 TDI (c0) ; +RUNTEST IDLE 100 TCK; +//Loading device with 'enable' instruction. +SIR 8 TDI (e8) ; +// Setting Done bit ... +// Loading device with a 'program' instruction. +ENDIR IRPAUSE; +SIR 8 TDI (ea) ; +SDR 281 TDI (0017fdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; +ENDIR IDLE; +RUNTEST 10000 TCK; +SIR 8 TDI (f0) SMASK (ff) ; +STATE IDLE; +RUNTEST IDLE 20 TCK; +ENDIR IRPAUSE; +SIR 8 TDI (f0) SMASK (ff) ; +STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; +RUNTEST 800 TCK; +ENDIR IDLE; +//Loading device with 'conld' instruction. +SIR 8 TDI (c0) ; +RUNTEST IDLE 100 TCK; +//Loading device with 'idcode' instruction. +SIR 8 TDI (01) ; +SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6e5f093) MASK (0fff8fff) ; +//Check for Done bit. +SIR 8 TDI (ff) TDO (05) MASK (07) ; +TIR 0 ; +HIR 0 ; +HDR 0 ; +TDR 0 ; +TIR 0 ; +HIR 0 ; +HDR 0 ; +TDR 0 ; +TIR 0 ; +HIR 0 ; +TDR 0 ; +HDR 0 ; +SIR 8 TDI (ff) ; +SDR 1 TDI (00) SMASK (01) ; From 1d58f0516384555c874bb2616fd7037c2acd1afc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 15:50:36 -0700 Subject: [PATCH 141/165] JTAG: Auto-generate HackRF CPLD data from SVF. --- firmware/CMakeLists.txt | 5 +++++ firmware/application/CMakeLists.txt | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index d63a3b54..9a7bb2d1 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -26,7 +26,12 @@ set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu) set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME}) + +set(HACKRF_CPLD_SVF_FILENAME hackrf_cpld_default.svf) +set(HACKRF_CPLD_SVF_PATH ${PROJECT_SOURCE_DIR}/${HACKRF_CPLD_SVF_FILENAME}) + set(EXTRACT_CPLD_DATA ${PROJECT_SOURCE_DIR}/tools/extract_cpld_data.py) +set(EXTRACT_SVF_DATA_XC2C64A ${PROJECT_SOURCE_DIR}/tools/extract_svf_data_xc2c64a.py) set(STRIP_DFU ${PROJECT_SOURCE_DIR}/tools/strip_dfu.py) set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py) set(MAKE_IMAGE_CHUNK ${PROJECT_SOURCE_DIR}/tools/make_image_chunk.py) diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 46de19ba..f4190523 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -74,6 +74,9 @@ set(USE_FPU no) set(CPLD_SVF_PATH ${HARDWARE_PATH}/portapack_h1/cpld/output_files/portapack_h1_cpld.svf) set(CPLD_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/portapack_cpld_data.cpp) +set(HACKRF_CPLD_DATA_HPP ${CMAKE_CURRENT_BINARY_DIR}/hackrf_cpld_data.hpp) +set(HACKRF_CPLD_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/hackrf_cpld_data.cpp) + # Imported source files and paths include(${CHIBIOS_PORTAPACK}/boards/GSG_HACKRF_ONE/board.cmake) include(${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M0/platform.cmake) @@ -181,9 +184,12 @@ set(CPPSRC ${COMMON}/lfsr_random.cpp core_control.cpp ${COMMON}/cpld_max5.cpp + ${COMMON}/cpld_xilinx.cpp ${COMMON}/jtag.cpp + ${COMMON}/jtag_tap.cpp cpld_update.cpp ${CPLD_DATA_CPP} + ${HACKRF_CPLD_DATA_CPP} ) # C sources to be compiled in ARM mode regardless of the global setting. @@ -209,7 +215,7 @@ set(TCPPSRC) # List ASM source files here set(ASMSRC ${PORTASM}) -set(INCDIR ${COMMON} ${PORTINC} ${KERNINC} ${TESTINC} +set(INCDIR ${CMAKE_CURRENT_BINARY_DIR} ${COMMON} ${PORTINC} ${KERNINC} ${TESTINC} ${HALINC} ${PLATFORMINC} ${BOARDINC} ${FATFSINC} ${CHIBIOS}/os/various @@ -303,6 +309,12 @@ add_custom_command( DEPENDS ${EXTRACT_CPLD_DATA} ${CPLD_SVF_PATH} ) +add_custom_command( + OUTPUT ${HACKRF_CPLD_DATA_HPP} ${HACKRF_CPLD_DATA_CPP} + COMMAND ${EXTRACT_SVF_DATA_XC2C64A} ${HACKRF_CPLD_SVF_PATH} hackrf::one::cpld::verify_blocks ${HACKRF_CPLD_DATA_HPP} ${HACKRF_CPLD_DATA_CPP} + DEPENDS ${EXTRACT_SVF_DATA_XC2C64A} ${HACKRF_CPLD_SVF_PATH} +) + add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC}) set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_DEPENDS ${LDSCRIPT}) add_definitions(${DEFS}) From c8b1a8fbf6a1e715824b9cedf896eb5baf5a00cb Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 15:52:58 -0700 Subject: [PATCH 142/165] JTAG: Add functions to check EEPROM, load SRAM of HackRF CPLD. --- firmware/application/cpld_update.cpp | 31 ++++++++++++++++++++++++++++ firmware/application/cpld_update.hpp | 3 +++ 2 files changed, 34 insertions(+) diff --git a/firmware/application/cpld_update.cpp b/firmware/application/cpld_update.cpp index 6207c69e..64134e83 100644 --- a/firmware/application/cpld_update.cpp +++ b/firmware/application/cpld_update.cpp @@ -21,11 +21,14 @@ #include "cpld_update.hpp" +#include "hackrf_gpio.hpp" #include "portapack_hal.hpp" #include "jtag_target_gpio.hpp" #include "cpld_max5.hpp" +#include "cpld_xilinx.hpp" #include "portapack_cpld_data.hpp" +#include "hackrf_cpld_data.hpp" bool cpld_update_if_necessary() { jtag::GPIOTarget target { @@ -82,3 +85,31 @@ bool cpld_update_if_necessary() { return ok; } + +static jtag::GPIOTarget jtag_target_hackrf() { + return { + hackrf::one::gpio_cpld_tck, + hackrf::one::gpio_cpld_tms, + hackrf::one::gpio_cpld_tdi, + hackrf::one::gpio_cpld_tdo, + }; +} + +bool cpld_hackrf_load_sram() { + auto jtag_target_hackrf_cpld = jtag_target_hackrf(); + cpld::xilinx::XC2C64A hackrf_cpld { jtag_target_hackrf_cpld }; + + hackrf_cpld.write_sram(hackrf::one::cpld::verify_blocks); + const auto ok = hackrf_cpld.verify_sram(hackrf::one::cpld::verify_blocks); + + return ok; +} + +bool cpld_hackrf_verify_eeprom() { + auto jtag_target_hackrf_cpld = jtag_target_hackrf(); + cpld::xilinx::XC2C64A hackrf_cpld { jtag_target_hackrf_cpld }; + + const auto ok = hackrf_cpld.verify_eeprom(hackrf::one::cpld::verify_blocks); + + return ok; +} diff --git a/firmware/application/cpld_update.hpp b/firmware/application/cpld_update.hpp index 236b2fe0..bd317e10 100644 --- a/firmware/application/cpld_update.hpp +++ b/firmware/application/cpld_update.hpp @@ -24,4 +24,7 @@ bool cpld_update_if_necessary(); +bool cpld_hackrf_load_sram(); +bool cpld_hackrf_verify_eeprom(); + #endif/*__CPLD_UPDATE_H__*/ From 204408d288418619526da0f49769e29dadbf9f14 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 15:54:02 -0700 Subject: [PATCH 143/165] JTAG: Load HackRF CPLD bitstream into SRAM from firmware image. No further concerns about the HackRF CPLD having an ancient bitstream on it! At least in PortaPack mode... --- firmware/application/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 93d496d3..3bea477e 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -76,6 +76,10 @@ int main(void) { chSysHalt(); } + if( !cpld_hackrf_load_sram() ) { + chSysHalt(); + } + portapack::io.init(); portapack::display.init(); From 3f3fe3bb6780c055f943a85b317f0623657dbcaf Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 15:56:24 -0700 Subject: [PATCH 144/165] JTAG: Report if HackRF CPLD bitstream matches released version. TODO: Could be better reporting (CRC?), and could not pause while checking CPLD EEPROM, and could offer a means to program the bitstream if it doesn't match... --- firmware/application/ui_setup.cpp | 9 +++++++++ firmware/application/ui_setup.hpp | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/firmware/application/ui_setup.cpp b/firmware/application/ui_setup.cpp index da662404..5a10b20e 100644 --- a/firmware/application/ui_setup.cpp +++ b/firmware/application/ui_setup.cpp @@ -28,6 +28,8 @@ using namespace lpc43xx; #include "portapack.hpp" using portapack::receiver_model; +#include "cpld_update.hpp" + namespace ui { SetDateTimeView::SetDateTimeView( @@ -172,10 +174,17 @@ AboutView::AboutView(NavigationView& nav) { &text_title, &text_firmware, &text_cpld_hackrf, + &text_cpld_hackrf_status, &button_ok, } }); button_ok.on_select = [&nav](Button&){ nav.pop(); }; + + if( cpld_hackrf_verify_eeprom() ) { + text_cpld_hackrf_status.set(" OK"); + } else { + text_cpld_hackrf_status.set("BAD"); + } } void AboutView::focus() { diff --git a/firmware/application/ui_setup.hpp b/firmware/application/ui_setup.hpp index 016d11ab..d65592c4 100644 --- a/firmware/application/ui_setup.hpp +++ b/firmware/application/ui_setup.hpp @@ -235,8 +235,13 @@ private: }; Text text_cpld_hackrf { - { 0, 144, 240, 16 }, - "HackRF CPLD CRC 0x????????", + { 0, 144, 11*8, 16 }, + "HackRF CPLD", + }; + + Text text_cpld_hackrf_status { + { 240 - 3*8, 144, 3*8, 16 }, + "???" }; Button button_ok { From 5390c45e0448bb9be7cb87e71bf0ac1630144532 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jul 2016 16:16:13 -0700 Subject: [PATCH 145/165] Fix Python 2 vs 3 breakage relating to hex(). In Python 2, hex() of large ints has a "L" on the end. --- firmware/tools/extract_svf_data_xc2c64a.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/tools/extract_svf_data_xc2c64a.py b/firmware/tools/extract_svf_data_xc2c64a.py index ee504c3c..1c1b8c1b 100755 --- a/firmware/tools/extract_svf_data_xc2c64a.py +++ b/firmware/tools/extract_svf_data_xc2c64a.py @@ -44,11 +44,11 @@ f = open(args.input_file_path, 'r') namespaces, variable_name = crack_variable_path(args.variable_path) def to_hex(value, length_bits): - return hex(value)[2:].zfill((length_bits + 3) >> 2) + return ('%x' % value).zfill((length_bits + 3) >> 2) def long_int_to_bytes(n, bit_count): byte_count = (bit_count + 7) >> 3 - h = hex(n)[2:].zfill(byte_count * 2) + h = ('%x' % n).zfill(byte_count * 2) return [int(h[n:n+2], 16) for n in range(0, len(h), 2)] re_sdr = re.compile(r'^(?P\d+)\s*TDI\s*\((?P[0-9A-F]+)\)(|\s*SMASK\s*\((?P[0-9A-F]+)\))(|\s*TDO\s*\((?P[0-9A-F]+)\))(|\s*MASK\s*\((?P[0-9A-F]+)\))\s*;$') From c0b9761fe5c20a6dc8c648cff49072c34db30179 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 18 Jul 2016 11:30:45 -0700 Subject: [PATCH 146/165] Move CPLD management into PortaPack::init(). --- firmware/application/main.cpp | 10 ---------- firmware/application/portapack.cpp | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 3bea477e..05ce816e 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -24,8 +24,6 @@ #include "portapack.hpp" #include "portapack_shared_memory.hpp" -#include "cpld_update.hpp" - #include "message_queue.hpp" #include "ui.hpp" @@ -72,14 +70,6 @@ static void event_loop() { int main(void) { portapack::init(); - if( !cpld_update_if_necessary() ) { - chSysHalt(); - } - - if( !cpld_hackrf_load_sram() ) { - chSysHalt(); - } - portapack::io.init(); portapack::display.init(); diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index 0aabc219..344f0aa8 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -32,6 +32,8 @@ using namespace hackrf::one; #include "touch_adc.hpp" #include "audio.hpp" +#include "cpld_update.hpp" + namespace portapack { portapack::IO io { @@ -149,6 +151,14 @@ void init() { radio::init(); touch::adc::init(); + + if( !cpld_update_if_necessary() ) { + chSysHalt(); + } + + if( !cpld_hackrf_load_sram() ) { + chSysHalt(); + } } void shutdown() { From 4b7fa9f411c5c3ea11973b143345ea89dda850a6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 18 Jul 2016 11:31:21 -0700 Subject: [PATCH 147/165] CPLD: Add XC2C64A method to init from EEPROM contents. --- firmware/common/cpld_xilinx.cpp | 34 +++++++++++++++++++++++++++++++++ firmware/common/cpld_xilinx.hpp | 4 ++++ 2 files changed, 38 insertions(+) diff --git a/firmware/common/cpld_xilinx.cpp b/firmware/common/cpld_xilinx.cpp index 7cc6b79d..4690f665 100644 --- a/firmware/common/cpld_xilinx.cpp +++ b/firmware/common/cpld_xilinx.cpp @@ -116,6 +116,23 @@ bool XC2C64A::verify_eeprom(const verify_blocks_t& blocks) { return !error; } +void XC2C64A::init_from_eeprom() { + tap.set_repeat(0); + tap.set_end_ir(state_t::run_test_idle); + tap.set_end_dr(state_t::run_test_idle); + + reset(); + enable(); + + discharge(); + init(); + + disable(); + bypass(); + + tap.state(state_t::test_logic_reset); +} + bool XC2C64A::shift_ir(const instruction_t instruction) { const ir_t ir_buffer = toUType(instruction); const jtag::tap::bits_t bits { &ir_buffer, ir_length }; @@ -132,6 +149,23 @@ void XC2C64A::enable() { tap.wait(state_t::run_test_idle, state_t::run_test_idle, 800); } +void XC2C64A::enable_otf() { + shift_ir(instruction_t::ISC_ENABLE_OTF); +} + +void XC2C64A::discharge() { + shift_ir(instruction_t::ISC_INIT); + tap.wait(state_t::run_test_idle, state_t::run_test_idle, 20); +} + +void XC2C64A::init() { + tap.set_end_ir(state_t::update_ir); + shift_ir(instruction_t::ISC_INIT); + tap.set_end_ir(state_t::run_test_idle); + tap.state(state_t::capture_dr); + tap.wait(state_t::run_test_idle, state_t::run_test_idle, 800); +} + void XC2C64A::disable() { shift_ir(instruction_t::ISC_DISABLE); tap.wait(state_t::run_test_idle, state_t::run_test_idle, 100); diff --git a/firmware/common/cpld_xilinx.hpp b/firmware/common/cpld_xilinx.hpp index 36f7476a..ce702042 100644 --- a/firmware/common/cpld_xilinx.hpp +++ b/firmware/common/cpld_xilinx.hpp @@ -67,6 +67,7 @@ public: bool verify_sram(const verify_blocks_t& blocks); bool verify_eeprom(const verify_blocks_t& blocks); + void init_from_eeprom(); private: static constexpr size_t idcode_length = 32; @@ -112,6 +113,9 @@ private: void reset(); void enable(); + void enable_otf(); + void discharge(); + void init(); void disable(); bool bypass(); }; From 77291b4e3118fbda59464d95a865f074b5e0cc03 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 18 Jul 2016 11:32:14 -0700 Subject: [PATCH 148/165] On PortaPack shutdown, init HackRF CPLD to EEPROM bitstream. --- firmware/application/cpld_update.cpp | 7 +++++++ firmware/application/cpld_update.hpp | 1 + firmware/application/portapack.cpp | 3 +++ 3 files changed, 11 insertions(+) diff --git a/firmware/application/cpld_update.cpp b/firmware/application/cpld_update.cpp index 64134e83..cafa81cb 100644 --- a/firmware/application/cpld_update.cpp +++ b/firmware/application/cpld_update.cpp @@ -113,3 +113,10 @@ bool cpld_hackrf_verify_eeprom() { return ok; } + +void cpld_hackrf_init_from_eeprom() { + auto jtag_target_hackrf_cpld = jtag_target_hackrf(); + cpld::xilinx::XC2C64A hackrf_cpld { jtag_target_hackrf_cpld }; + + hackrf_cpld.init_from_eeprom(); +} diff --git a/firmware/application/cpld_update.hpp b/firmware/application/cpld_update.hpp index bd317e10..17c42bd5 100644 --- a/firmware/application/cpld_update.hpp +++ b/firmware/application/cpld_update.hpp @@ -26,5 +26,6 @@ bool cpld_update_if_necessary(); bool cpld_hackrf_load_sram(); bool cpld_hackrf_verify_eeprom(); +void cpld_hackrf_init_from_eeprom(); #endif/*__CPLD_UPDATE_H__*/ diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index 344f0aa8..16986c17 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -166,6 +166,9 @@ void shutdown() { radio::disable(); audio::shutdown(); + + cpld_hackrf_init_from_eeprom(); + clock_manager.shutdown(); power.shutdown(); From a98ada0cb76c62af444d250c7ad494ab3959ff38 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Jul 2016 10:47:15 -0700 Subject: [PATCH 149/165] Extract FrequencyStepView from FrequencyOptionsView. ...for use in capture app. --- firmware/application/ui_receiver.cpp | 6 ++-- firmware/application/ui_receiver.hpp | 43 +++++++++++++++++----------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/firmware/application/ui_receiver.cpp b/firmware/application/ui_receiver.cpp index 479d4468..18a5c613 100644 --- a/firmware/application/ui_receiver.cpp +++ b/firmware/application/ui_receiver.cpp @@ -232,7 +232,7 @@ FrequencyOptionsView::FrequencyOptionsView( { set_style(style); - options_step.on_change = [this](size_t n, OptionsField::value_t v) { + field_step.on_change = [this](size_t n, OptionsField::value_t v) { (void)n; this->on_step_changed(v); }; @@ -243,14 +243,14 @@ FrequencyOptionsView::FrequencyOptionsView( add_children({ { &text_step, - &options_step, + &field_step, &field_ppm, &text_ppm, } }); } void FrequencyOptionsView::set_step(rf::Frequency f) { - options_step.set_by_value(f); + field_step.set_by_value(f); } void FrequencyOptionsView::set_reference_ppm_correction(int32_t v) { diff --git a/firmware/application/ui_receiver.hpp b/firmware/application/ui_receiver.hpp index 12ab961c..1d4cb6d3 100644 --- a/firmware/application/ui_receiver.hpp +++ b/firmware/application/ui_receiver.hpp @@ -229,6 +229,32 @@ private: void update_text(); }; +class FrequencyStepView : public OptionsField { +public: + FrequencyStepView( + Point parent_pos + ) : OptionsField { + parent_pos, + 5, + { + { " 100", 100 }, + { " 1k ", 1000 }, + { " 3k ", 3000 }, /* Approximate SSB bandwidth */ + { " 5k ", 5000 }, + { " 6k3", 6250 }, + { " 9k ", 9000 }, /* channel spacing for LF, MF in some regions */ + { " 10k ", 10000 }, + { " 12k5", 12500 }, + { " 25k ", 25000 }, + { "100k ", 100000 }, + { " 1M ", 1000000 }, + { " 10M ", 10000000 }, + } + } + { + } +}; + class FrequencyOptionsView : public View { public: std::function on_change_step; @@ -245,23 +271,8 @@ private: "Step" }; - OptionsField options_step { + FrequencyStepView field_step { { 5 * 8, 0 * 16 }, - 5, - { - { " 100", 100 }, - { " 1k ", 1000 }, - { " 3k ", 3000 }, /* Approximate SSB bandwidth */ - { " 5k ", 5000 }, - { " 6k3", 6250 }, - { " 9k ", 9000 }, /* channel spacing for LF, MF in some regions */ - { " 10k ", 10000 }, - { " 12k5", 12500 }, - { " 25k ", 25000 }, - { "100k ", 100000 }, - { " 1M ", 1000000 }, - { " 10M ", 10000000 }, - } }; void on_step_changed(rf::Frequency v); From 6f65cdf41e353426fa5b86c4add2151463e20ff5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Jul 2016 10:48:45 -0700 Subject: [PATCH 150/165] Add frequency step control to capture app. Redistribute other controls, remove empty row that had been reserved for options views. --- firmware/application/capture_app.cpp | 7 +++++++ firmware/application/capture_app.hpp | 24 ++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 9d1761a2..1ccc9aa9 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -38,6 +38,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { &rssi, &channel, &field_frequency, + &field_frequency_step, &field_rf_amp, &field_lna, &field_vga, @@ -59,6 +60,12 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { }; }; + field_frequency_step.set_by_value(receiver_model.frequency_step()); + field_frequency_step.on_change = [this](size_t, OptionsField::value_t v) { + receiver_model.set_frequency_step(v); + this->field_frequency.set_step(v); + }; + radio::enable({ tuning_frequency(), sampling_rate, diff --git a/firmware/application/capture_app.hpp b/firmware/application/capture_app.hpp index e6a4b90e..a7d04859 100644 --- a/firmware/application/capture_app.hpp +++ b/firmware/application/capture_app.hpp @@ -47,7 +47,7 @@ public: std::string title() const override { return "Capture"; }; private: - static constexpr ui::Dim header_height = 3 * 16; + static constexpr ui::Dim header_height = 2 * 16; static constexpr uint32_t sampling_rate = 4000000; static constexpr uint32_t baseband_bandwidth = 2500000; @@ -60,31 +60,35 @@ private: rf::Frequency tuning_frequency() const; RSSI rssi { - { 21 * 8, 0, 6 * 8, 4 }, + { 24 * 8, 0, 6 * 8, 4 }, }; Channel channel { - { 21 * 8, 5, 6 * 8, 4 }, + { 24 * 8, 5, 6 * 8, 4 }, }; FrequencyField field_frequency { - { 3 * 8, 0 * 16 }, + { 0 * 8, 0 * 16 }, + }; + + FrequencyStepView field_frequency_step { + { 10 * 8, 0 * 16 }, }; RFAmpField field_rf_amp { - { 13 * 8, 0 * 16 } + { 16 * 8, 0 * 16 } }; LNAGainField field_lna { - { 15 * 8, 0 * 16 } - }; - - VGAGainField field_vga { { 18 * 8, 0 * 16 } }; + VGAGainField field_vga { + { 21 * 8, 0 * 16 } + }; + RecordView record_view { - { 0 * 8, 2 * 16, 30 * 8, 1 * 16 }, + { 0 * 8, 1 * 16, 30 * 8, 1 * 16 }, "BBD_????", RecordView::FileType::RawS16, 16384, 3 }; From 2993f7be1d0338787081dcb28fc51dfc1c083392 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Jul 2016 11:00:31 -0700 Subject: [PATCH 151/165] SDIO: Commit optional code to run at 50MHz. --- .../chibios-portapack/os/hal/platforms/LPC43xx/sdc_lld.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/sdc_lld.c b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/sdc_lld.c index e5483012..f593c5f2 100644 --- a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/sdc_lld.c +++ b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/sdc_lld.c @@ -200,8 +200,14 @@ static void sdio_cclk_set_400khz(void) { } static void sdio_cclk_set_fast(void) { +#if defined(PORTAPACK_FAST_SDIO) + /* 200MHz / (2 * 2) = 50MHz */ + /* TODO: Adjust SCU pin configurations: pull-up/down, slew, glitch filter? */ + sdio_cclk_set(2); +#else /* 200MHz / (2 * 4) = 25MHz */ sdio_cclk_set(4); +#endif } static void sdio_width_set_1bit(void) { From ff9c911a9388047784a782e19d1963ed2271d766 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Jul 2016 11:02:30 -0700 Subject: [PATCH 152/165] Optional code to disable baseband DMA synchronization. --- firmware/baseband/baseband_dma.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/firmware/baseband/baseband_dma.cpp b/firmware/baseband/baseband_dma.cpp index f5dcca1e..d86bef72 100644 --- a/firmware/baseband/baseband_dma.cpp +++ b/firmware/baseband/baseband_dma.cpp @@ -115,9 +115,16 @@ static void dma_error() { void init() { gpdma_channel_sgpio.set_handlers(transfer_complete, dma_error); - - // LPC_GPDMA->SYNC |= (1 << gpdma_src_peripheral); - // LPC_GPDMA->SYNC |= (1 << gpdma_dest_peripheral); +#if defined(PORTAPACK_BASEBAND_DMA_NO_SYNC) + /* Disable synchronization logic to improve(?) DMA response time. + * SGPIO (peripheral) must be on same clock as GPDMA peripheral. + * SGPIO runs from BASE_PERIPH_CLK, which is set to PLL1 in normal + * operation, same as the M4 and M0 cores. Memory, of course, is + * running from the same clock as the cores. + */ + LPC_GPDMA->SYNC |= (1 << gpdma_src_peripheral); + LPC_GPDMA->SYNC |= (1 << gpdma_dest_peripheral); +#endif } void configure( From 3c46abdb2465a73d2924f693dc41b11c1f728ee2 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Jul 2016 14:25:56 -0700 Subject: [PATCH 153/165] Remove redundant #include. --- firmware/baseband/proc_wideband_spectrum.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/firmware/baseband/proc_wideband_spectrum.cpp b/firmware/baseband/proc_wideband_spectrum.cpp index 57268198..c90fbad9 100644 --- a/firmware/baseband/proc_wideband_spectrum.cpp +++ b/firmware/baseband/proc_wideband_spectrum.cpp @@ -25,8 +25,6 @@ #include "dsp_fft.hpp" -#include "event_m4.hpp" - #include #include From 74b5571e8bffce769e6fb5a1b7ec71885ce6c326 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Jul 2016 17:06:22 -0700 Subject: [PATCH 154/165] Remove baseband::start()/stop() and related message. --- firmware/application/ais_app.cpp | 7 ------- firmware/application/baseband_api.cpp | 12 ------------ firmware/application/baseband_api.hpp | 3 --- firmware/application/capture_app.cpp | 7 ------- firmware/application/ert_app.cpp | 7 ------- firmware/application/receiver_model.cpp | 5 ----- firmware/application/tpms_app.cpp | 7 ------- firmware/common/message.hpp | 13 ------------- 8 files changed, 61 deletions(-) diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index 39cc0e14..543e5553 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -308,12 +308,6 @@ AISAppView::AISAppView(NavigationView&) { 1, }); - baseband::start({ - .mode = 3, - .sampling_rate = sampling_rate, - .decimation_factor = 1, - }); - options_channel.on_change = [this](size_t, OptionsField::value_t v) { this->on_frequency_changed(v); }; @@ -333,7 +327,6 @@ AISAppView::AISAppView(NavigationView&) { } AISAppView::~AISAppView() { - baseband::stop(); radio::disable(); baseband::shutdown(); diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index a28be777..35738010 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -78,18 +78,6 @@ void WFMConfig::apply() const { audio::set_rate(audio::Rate::Hz_48000); } -void start(BasebandConfiguration configuration) { - BasebandConfigurationMessage message { configuration }; - send_message(&message); -} - -void stop() { - BasebandConfigurationMessage message { - .configuration = { }, - }; - send_message(&message); -} - static bool baseband_image_running = false; void run_image(const portapack::spi_flash::image_tag_t image_tag) { diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index c12b08fd..10f57a86 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -52,9 +52,6 @@ struct WFMConfig { void apply() const; }; -void start(BasebandConfiguration configuration); -void stop(); - void run_image(const portapack::spi_flash::image_tag_t image_tag); void shutdown(); diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 1ccc9aa9..87d40114 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -77,12 +77,6 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { 1, }); - baseband::start({ - .mode = toUType(ReceiverModel::Mode::Capture), - .sampling_rate = sampling_rate, - .decimation_factor = 1, - }); - record_view.set_sampling_rate(sampling_rate / 8); record_view.on_error = [&nav](std::string message) { nav.display_modal("Error", message); @@ -90,7 +84,6 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { } CaptureAppView::~CaptureAppView() { - baseband::stop(); radio::disable(); baseband::shutdown(); diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 711f1284..269b1096 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -136,12 +136,6 @@ ERTAppView::ERTAppView(NavigationView&) { 1, }); - baseband::start({ - .mode = 6, - .sampling_rate = sampling_rate, - .decimation_factor = 1, - }); - logger = std::make_unique(); if( logger ) { logger->append("ert.txt"); @@ -149,7 +143,6 @@ ERTAppView::ERTAppView(NavigationView&) { } ERTAppView::~ERTAppView() { - baseband::stop(); radio::disable(); baseband::shutdown(); diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index cf8607b8..bd5def05 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -154,7 +154,6 @@ void ReceiverModel::enable() { void ReceiverModel::disable() { enabled_ = false; update_antenna_bias(); - baseband::stop(); // TODO: Responsibility for enabling/disabling the radio is muddy. // Some happens in ReceiverModel, some inside radio namespace. @@ -225,13 +224,9 @@ void ReceiverModel::update_baseband_configuration() { // protocols that need quick RX/TX turn-around. // Disabling baseband while changing sampling rates seems like a good idea... - baseband::stop(); - radio::set_baseband_rate(sampling_rate() * baseband_oversampling()); update_tuning_frequency(); radio::set_baseband_decimation_by(baseband_oversampling()); - - baseband::start(baseband_configuration); } void ReceiverModel::update_headphone_volume() { diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index a56c97e8..0c96971c 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -187,12 +187,6 @@ TPMSAppView::TPMSAppView(NavigationView&) { 1, }); - baseband::start({ - .mode = 5, - .sampling_rate = sampling_rate, - .decimation_factor = 1, - }); - options_band.on_change = [this](size_t, OptionsField::value_t v) { this->on_band_changed(v); }; @@ -205,7 +199,6 @@ TPMSAppView::TPMSAppView(NavigationView&) { } TPMSAppView::~TPMSAppView() { - baseband::stop(); radio::disable(); baseband::shutdown(); diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 725c328b..1e560ba4 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -51,7 +51,6 @@ public: ChannelStatistics = 2, DisplayFrameSync = 3, AudioStatistics = 4, - BasebandConfiguration = 5, TPMSPacket = 6, Shutdown = 8, AISPacket = 7, @@ -213,18 +212,6 @@ struct BasebandConfiguration { } }; -class BasebandConfigurationMessage : public Message { -public: - constexpr BasebandConfigurationMessage( - const BasebandConfiguration& configuration - ) : Message { ID::BasebandConfiguration }, - configuration { configuration } - { - } - - BasebandConfiguration configuration; -}; - class SpectrumStreamingConfigMessage : public Message { public: enum class Mode : uint32_t { From 49d6cda73161bf75b984737433ef98168d602d3f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Jul 2016 17:11:32 -0700 Subject: [PATCH 155/165] Move BasebandConfiguration to receiver_model.hpp. That's the only place it's being used now -- it's no longer moving between cores. --- firmware/application/receiver_model.hpp | 21 +++++++++++++++++++++ firmware/common/message.hpp | 21 --------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index ad664700..e9ab0efb 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -30,6 +30,27 @@ #include "max2837.hpp" #include "volume.hpp" +struct BasebandConfiguration { + int32_t mode; + uint32_t sampling_rate; + size_t decimation_factor; + + constexpr BasebandConfiguration( + int32_t mode, + uint32_t sampling_rate, + size_t decimation_factor = 1 + ) : mode { mode }, + sampling_rate { sampling_rate }, + decimation_factor { decimation_factor } + { + } + + constexpr BasebandConfiguration( + ) : BasebandConfiguration { -1, 0, 1 } + { + } +}; + class ReceiverModel { public: enum class Mode : int32_t { diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 1e560ba4..a4030b5f 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -191,27 +191,6 @@ public: AudioStatistics statistics; }; -struct BasebandConfiguration { - int32_t mode; - uint32_t sampling_rate; - size_t decimation_factor; - - constexpr BasebandConfiguration( - int32_t mode, - uint32_t sampling_rate, - size_t decimation_factor = 1 - ) : mode { mode }, - sampling_rate { sampling_rate }, - decimation_factor { decimation_factor } - { - } - - constexpr BasebandConfiguration( - ) : BasebandConfiguration { -1, 0, 1 } - { - } -}; - class SpectrumStreamingConfigMessage : public Message { public: enum class Mode : uint32_t { From b3f4ea897807b426c6b3583b443aed7976b5da1c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 15:27:05 -0700 Subject: [PATCH 156/165] Clean up SharedMemory placement new. --- firmware/application/event_m0.cpp | 9 +-------- firmware/common/portapack_shared_memory.hpp | 12 ++++++------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 6f291dd3..d40d60a9 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -322,14 +322,7 @@ void EventDispatcher::event_bubble_encoder(const ui::EncoderEvent event) { } void EventDispatcher::init_message_queues() { - shared_memory.baseband_message = nullptr; - new (&shared_memory.application_queue) MessageQueue( - shared_memory.application_queue_data, SharedMemory::application_queue_k - ); - new (&shared_memory.app_local_queue) MessageQueue( - shared_memory.app_local_queue_data, SharedMemory::app_local_queue_k - ); - shared_memory.m4_panic_msg[0] = 0; + new (&shared_memory) SharedMemory; } MessageHandlerRegistration::MessageHandlerRegistration( diff --git a/firmware/common/portapack_shared_memory.hpp b/firmware/common/portapack_shared_memory.hpp index 3ef6ec98..a509473e 100644 --- a/firmware/common/portapack_shared_memory.hpp +++ b/firmware/common/portapack_shared_memory.hpp @@ -36,17 +36,17 @@ struct SharedMemory { static constexpr size_t application_queue_k = 11; static constexpr size_t app_local_queue_k = 11; - uint8_t application_queue_data[1 << application_queue_k]; - uint8_t app_local_queue_data[1 << app_local_queue_k]; - const Message* volatile baseband_message; - MessageQueue application_queue; - MessageQueue app_local_queue; // TODO: M0 should directly configure and control DMA channel that is // acquiring ADC samples. TouchADCFrame touch_adc_frame; + uint8_t application_queue_data[1 << application_queue_k] { 0 }; + uint8_t app_local_queue_data[1 << app_local_queue_k] { 0 }; + const Message* volatile baseband_message { nullptr }; + MessageQueue application_queue { application_queue_data, application_queue_k }; + MessageQueue app_local_queue { app_local_queue_data, app_local_queue_k }; - char m4_panic_msg[32]; + char m4_panic_msg[32] { 0 }; }; extern SharedMemory& shared_memory; From 8b02e40602e6813b4cd4c31e1d9e9cd018176100 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 15:31:53 -0700 Subject: [PATCH 157/165] Move touch ADC data collection to M0. ...so it continues when M4 is shut down. It's not as pretty as using DMA, but it's far simpler, even if it involves letting the ADC run continuously and taking the last samples even if not synchronizing to the phase of the sampling of the channels. --- firmware/application/irq_controls.cpp | 4 +-- firmware/application/touch_adc.cpp | 27 ++++++--------------- firmware/baseband/CMakeLists.txt | 1 - firmware/baseband/main.cpp | 6 ----- firmware/common/portapack_shared_memory.hpp | 8 ------ 5 files changed, 10 insertions(+), 36 deletions(-) diff --git a/firmware/application/irq_controls.cpp b/firmware/application/irq_controls.cpp index 5a789721..cb6a2df5 100644 --- a/firmware/application/irq_controls.cpp +++ b/firmware/application/irq_controls.cpp @@ -168,8 +168,6 @@ void timer0_callback(GPTDriver* const) { EventDispatcher::events_flag_isr(event_mask); chSysUnlockFromIsr(); } - - touch::adc::start(); } /* TODO: Refactor some/all of this to appropriate shared headers? */ @@ -187,6 +185,8 @@ static GPTConfig timer0_config { }; void controls_init() { + touch::adc::start(); + /* GPT timer 0 is used to scan user interface controls -- touch screen, * navigation switches. */ diff --git a/firmware/application/touch_adc.cpp b/firmware/application/touch_adc.cpp index 0808f9fc..be731282 100644 --- a/firmware/application/touch_adc.cpp +++ b/firmware/application/touch_adc.cpp @@ -70,26 +70,15 @@ void start() { // static constexpr bool monitor_overruns_and_not_dones = false; Samples get() { - const auto& frame = shared_memory.touch_adc_frame; - const auto xp = frame.dr[portapack::adc0_touch_xp_input]; - const auto xn = frame.dr[portapack::adc0_touch_xn_input]; - const auto yp = frame.dr[portapack::adc0_touch_yp_input]; - const auto yn = frame.dr[portapack::adc0_touch_yn_input]; - - // if( monitor_overruns_and_not_dones ) { - // const auto dr_and = xp & xn & yp & yn; - // const auto dr_or = xp | xn | yp | yn; - // const bool done = (dr_and >> 31) & 1; - // const bool overrun = (dr_or >> 30) & 1; - // led_tx.write(overrun); - // led_rx.write(!done); - // } - + const auto xp_reg = LPC_ADC0->DR[portapack::adc0_touch_xp_input]; + const auto xn_reg = LPC_ADC0->DR[portapack::adc0_touch_xn_input]; + const auto yp_reg = LPC_ADC0->DR[portapack::adc0_touch_yp_input]; + const auto yn_reg = LPC_ADC0->DR[portapack::adc0_touch_yn_input]; return { - (xp >> 6) & 0x3ff, - (xn >> 6) & 0x3ff, - (yp >> 6) & 0x3ff, - (yn >> 6) & 0x3ff, + (xp_reg >> 6) & 0x3ff, + (xn_reg >> 6) & 0x3ff, + (yp_reg >> 6) & 0x3ff, + (yn_reg >> 6) & 0x3ff, }; } diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 2aaa3028..067b8dd2 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -128,7 +128,6 @@ set(CPPSRC audio_output.cpp audio_dma.cpp audio_stats_collector.cpp - touch_dma.cpp ${COMMON}/utility.cpp ${COMMON}/chibios_cpp.cpp ${COMMON}/debug.cpp diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index e99a0f34..c192f660 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -28,8 +28,6 @@ #include "gpdma.hpp" -#include "touch_dma.hpp" - #include "message_queue.hpp" #include "utility.hpp" @@ -73,10 +71,6 @@ static void init() { LPC_CREG->DMAMUX = portapack::gpdma_mux; gpdma::controller.enable(); nvicEnableVector(DMA_IRQn, CORTEX_PRIORITY_MASK(LPC_DMA_IRQ_PRIORITY)); - - touch::dma::init(); - touch::dma::allocate(); - touch::dma::enable(); } extern void run(); diff --git a/firmware/common/portapack_shared_memory.hpp b/firmware/common/portapack_shared_memory.hpp index a509473e..3ff738c9 100644 --- a/firmware/common/portapack_shared_memory.hpp +++ b/firmware/common/portapack_shared_memory.hpp @@ -27,19 +27,11 @@ #include "message_queue.hpp" -struct TouchADCFrame { - uint32_t dr[8]; -}; - /* NOTE: These structures must be located in the same location in both M4 and M0 binaries */ struct SharedMemory { static constexpr size_t application_queue_k = 11; static constexpr size_t app_local_queue_k = 11; - - // TODO: M0 should directly configure and control DMA channel that is - // acquiring ADC samples. - TouchADCFrame touch_adc_frame; uint8_t application_queue_data[1 << application_queue_k] { 0 }; uint8_t app_local_queue_data[1 << app_local_queue_k] { 0 }; const Message* volatile baseband_message { nullptr }; From 931853a55f0363ef4e22e4df58711cf9e4f4536c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 19:12:09 -0700 Subject: [PATCH 158/165] Make File::Result::value() const. --- firmware/application/file.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index 7504fb93..96b71991 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -154,7 +154,7 @@ public: return type == Type::Error; } - const T& value() { + const T& value() const { return value_; } From d556ef38b43141780f7131635260223f4e05894d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 19:12:37 -0700 Subject: [PATCH 159/165] File: Make incomplete write()s return FR_DISK_FULL. --- firmware/application/file.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index bcca3742..fa0658fe 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -78,7 +78,11 @@ File::Result File::write(const void* const data, const size_t bytes_to_w UINT bytes_written = 0; const auto result = f_write(&f, data, bytes_to_write, &bytes_written); if( result == FR_OK ) { - return { static_cast(bytes_written) }; + if( bytes_to_write == bytes_written ) { + return { static_cast(bytes_written) }; + } else { + return Error { FR_DISK_FULL }; + } } else { return { static_cast(result) }; } From ff17f8f2935a7dcddc34941630b38ca2f195f41c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 19:13:39 -0700 Subject: [PATCH 160/165] File: Do not use f_error() in puts(), it doesn't return the reason for failure. TODO: Improve puts() behavior to return a more specific error than FR_EOF. --- firmware/application/file.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index fa0658fe..814f3bde 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -105,10 +105,8 @@ File::Result File::puts(const std::string& string) { const auto result = f_puts(string.c_str(), &f); if( result >= 0 ) { return { static_cast(result) }; - } else if( result == EOF ) { - return { static_cast(f_error(&f)) }; } else { - return { static_cast(FR_UNEXPECTED) }; + return { static_cast(FR_EOF) }; } } From c2d971d59e4ef2d7611d213247c7cf2c09caad5e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 19:14:48 -0700 Subject: [PATCH 161/165] WAVFileWriter: Error handling while updating header. --- firmware/application/ui_record_view.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index 09627510..dca544b8 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -85,8 +85,7 @@ public: if( create_error.is_valid() ) { return create_error; } else { - update_header(); - return { }; + return update_header(); } } @@ -142,15 +141,22 @@ private: header_t header; - void update_header() { + Optional update_header() { header.set_data_size(bytes_written); - auto seek_result = file.seek(0); - if( seek_result.is_error() ) { - return; + const auto seek_0_result = file.seek(0); + if( seek_0_result.is_error() ) { + return seek_0_result.error(); } - const auto old_position = seek_result.value(); - file.write(&header, sizeof(header)); - file.seek(old_position); + const auto old_position = seek_0_result.value(); + const auto write_result = file.write(&header, sizeof(header)); + if( write_result.is_error() ) { + return write_result.error(); + } + const auto seek_old_result = file.seek(old_position); + if( seek_old_result.is_error() ) { + return seek_old_result.error(); + } + return { }; } }; From ffa797b9261fe70e141d009b993e78555f6384c0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 20:39:21 -0700 Subject: [PATCH 162/165] File: Remove puts(), add write_line(), cascade changes in interface. --- firmware/application/file.cpp | 17 +++++++++++------ firmware/application/file.hpp | 2 +- firmware/application/log_file.cpp | 12 ++++++------ firmware/application/log_file.hpp | 4 ++-- firmware/application/ui_record_view.cpp | 12 ++++++------ 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index 814f3bde..f4415452 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -101,13 +101,18 @@ File::Result File::seek(const uint64_t new_position) { return { static_cast(old_position) }; } -File::Result File::puts(const std::string& string) { - const auto result = f_puts(string.c_str(), &f); - if( result >= 0 ) { - return { static_cast(result) }; - } else { - return { static_cast(FR_EOF) }; +Optional File::write_line(const std::string& s) { + const auto result_s = write(s.c_str(), s.size()); + if( result_s.is_error() ) { + return { result_s.error() }; } + + const auto result_crlf = write("\r\n", 2); + if( result_crlf.is_error() ) { + return { result_crlf.error() }; + } + + return { }; } Optional File::sync() { diff --git a/firmware/application/file.hpp b/firmware/application/file.hpp index 96b71991..f3739317 100644 --- a/firmware/application/file.hpp +++ b/firmware/application/file.hpp @@ -207,7 +207,7 @@ public: return write(data.data(), N); } - Result puts(const std::string& string); + Optional write_line(const std::string& s); // TODO: Return Result<>. Optional sync(); diff --git a/firmware/application/log_file.cpp b/firmware/application/log_file.cpp index a761650f..fa82f4b1 100644 --- a/firmware/application/log_file.cpp +++ b/firmware/application/log_file.cpp @@ -23,15 +23,15 @@ #include "string_format.hpp" -File::Result LogFile::write_entry(const rtc::RTC& datetime, const std::string& entry) { +Optional LogFile::write_entry(const rtc::RTC& datetime, const std::string& entry) { std::string timestamp = to_string_timestamp(datetime); - return write(timestamp + " " + entry + "\r\n"); + return write_line(timestamp + " " + entry); } -File::Result LogFile::write(const std::string& message) { - auto puts_result = file.puts(message); - if( puts_result.is_ok() ) { +Optional LogFile::write_line(const std::string& message) { + auto error = file.write_line(message); + if( !error.is_valid() ) { file.sync(); } - return puts_result; + return error; } diff --git a/firmware/application/log_file.hpp b/firmware/application/log_file.hpp index 2aa515fa..1e1f667a 100644 --- a/firmware/application/log_file.hpp +++ b/firmware/application/log_file.hpp @@ -35,12 +35,12 @@ public: return file.append(filename); } - File::Result write_entry(const rtc::RTC& datetime, const std::string& entry); + Optional write_entry(const rtc::RTC& datetime, const std::string& entry); private: File file; - File::Result write(const std::string& message); + Optional write_line(const std::string& message); }; #endif/*__LOG_FILE_H__*/ diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index dca544b8..695a454d 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -320,13 +320,13 @@ Optional RecordView::write_metadata_file(const std::string& filenam if( create_error.is_valid() ) { return create_error; } else { - const auto puts_result1 = file.puts("sample_rate=" + to_string_dec_uint(sampling_rate) + "\n"); - if( puts_result1.is_error() ) { - return { puts_result1.error() }; + const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate)); + if( error_line1.is_valid() ) { + return error_line1; } - const auto puts_result2 = file.puts("center_frequency=" + to_string_dec_uint(receiver_model.tuning_frequency()) + "\n"); - if( puts_result2.is_error() ) { - return { puts_result2.error() }; + const auto error_line2 = file.write_line("center_frequency=" + to_string_dec_uint(receiver_model.tuning_frequency())); + if( error_line2.is_valid() ) { + return error_line2; } return { }; } From ea143bd3fc394a1e100728e4e811616929ce8ff7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 21:26:00 -0700 Subject: [PATCH 163/165] Move baseband init/shutdown code to before/after main(), not inside. --- firmware/baseband/main.cpp | 52 +++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index c192f660..1dc8a9fe 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -42,27 +42,6 @@ #include #include -extern "C" { - -void __late_init(void) { - /* - * System initializations. - * - HAL initialization, this also initializes the configured device drivers - * and performs the board-specific initializations. - * - Kernel initialization, the main() function becomes a thread and the - * RTOS is active. - */ - halInit(); - - /* After this call, scheduler, systick, heap, etc. are available. */ - /* By doing chSysInit() here, it runs before C++ constructors, which may - * require the heap. - */ - chSysInit(); -} - -} - static void init() { audio::dma::init(); audio::dma::configure(); @@ -82,7 +61,9 @@ static void halt() { } } -static void shutdown() { +extern "C" { + +void _default_exit(void) { // TODO: Is this complete? nvicDisableVector(DMA_IRQn); @@ -99,10 +80,29 @@ static void shutdown() { halt(); } -int main(void) { - init(); - run(); - shutdown(); +void __late_init(void) { + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + /* After this call, scheduler, systick, heap, etc. are available. */ + /* By doing chSysInit() here, it runs before C++ constructors, which may + * require the heap. + */ + chSysInit(); + + /* Baseband initialization */ + init(); +} + +} + +int main(void) { + run(); return 0; } From c8ffea0098eae3aa99d75384b091bdd01631c43f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 21:34:38 -0700 Subject: [PATCH 164/165] baseband: Move all init code into baseband.cpp. --- firmware/baseband/CMakeLists.txt | 1 + firmware/baseband/baseband.cpp | 89 ++++++++++++++++++++++++++++++++ firmware/baseband/main.cpp | 81 ----------------------------- 3 files changed, 90 insertions(+), 81 deletions(-) create mode 100644 firmware/baseband/baseband.cpp diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 067b8dd2..832cb5d8 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -97,6 +97,7 @@ set(CSRC # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. set(CPPSRC + baseband.cpp main.cpp ${COMMON}/message_queue.cpp ${COMMON}/event.cpp diff --git a/firmware/baseband/baseband.cpp b/firmware/baseband/baseband.cpp new file mode 100644 index 00000000..284b9471 --- /dev/null +++ b/firmware/baseband/baseband.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. + */ + +#include "ch.h" + +#include "lpc43xx_cpp.hpp" + +#include "portapack_shared_memory.hpp" +#include "portapack_dma.hpp" + +#include "gpdma.hpp" + +#include "audio_dma.hpp" + +static void init() { + audio::dma::init(); + audio::dma::configure(); + audio::dma::enable(); + + LPC_CREG->DMAMUX = portapack::gpdma_mux; + gpdma::controller.enable(); + nvicEnableVector(DMA_IRQn, CORTEX_PRIORITY_MASK(LPC_DMA_IRQ_PRIORITY)); +} + +static void halt() { + port_disable(); + while(true) { + port_wait_for_interrupt(); + } +} + +extern "C" { + +void __late_init(void) { + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + + /* After this call, scheduler, systick, heap, etc. are available. */ + /* By doing chSysInit() here, it runs before C++ constructors, which may + * require the heap. + */ + chSysInit(); + + /* Baseband initialization */ + init(); +} + +void _default_exit(void) { + // TODO: Is this complete? + + nvicDisableVector(DMA_IRQn); + + chSysDisable(); + + systick_stop(); + + ShutdownMessage shutdown_message; + shared_memory.application_queue.push(shutdown_message); + + shared_memory.baseband_message = nullptr; + + halt(); +} + +} diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index 1dc8a9fe..cfd20dd4 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -19,89 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#include "ch.h" - -#include "lpc43xx_cpp.hpp" - -#include "portapack_shared_memory.hpp" -#include "portapack_dma.hpp" - -#include "gpdma.hpp" - -#include "message_queue.hpp" - -#include "utility.hpp" - -#include "debug.hpp" - -#include "audio_dma.hpp" - -#include "gcc.hpp" - -#include -#include -#include - -static void init() { - audio::dma::init(); - audio::dma::configure(); - audio::dma::enable(); - - LPC_CREG->DMAMUX = portapack::gpdma_mux; - gpdma::controller.enable(); - nvicEnableVector(DMA_IRQn, CORTEX_PRIORITY_MASK(LPC_DMA_IRQ_PRIORITY)); -} - extern void run(); -static void halt() { - port_disable(); - while(true) { - port_wait_for_interrupt(); - } -} - -extern "C" { - -void _default_exit(void) { - // TODO: Is this complete? - - nvicDisableVector(DMA_IRQn); - - chSysDisable(); - - systick_stop(); - - ShutdownMessage shutdown_message; - shared_memory.application_queue.push(shutdown_message); - - shared_memory.baseband_message = nullptr; - - halt(); -} - -void __late_init(void) { - /* - * System initializations. - * - HAL initialization, this also initializes the configured device drivers - * and performs the board-specific initializations. - * - Kernel initialization, the main() function becomes a thread and the - * RTOS is active. - */ - halInit(); - - /* After this call, scheduler, systick, heap, etc. are available. */ - /* By doing chSysInit() here, it runs before C++ constructors, which may - * require the heap. - */ - chSysInit(); - - /* Baseband initialization */ - init(); -} - -} - int main(void) { run(); return 0; From fe1a6c09bbf8c4bdb53fb374d98166753d0e7d60 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 24 Jul 2016 21:42:11 -0700 Subject: [PATCH 165/165] Clean up baseband processors to each have a main(). --- firmware/baseband/CMakeLists.txt | 1 - firmware/baseband/main.cpp | 27 -------------------- firmware/baseband/proc_ais.cpp | 3 ++- firmware/baseband/proc_am_audio.cpp | 3 ++- firmware/baseband/proc_capture.cpp | 3 ++- firmware/baseband/proc_ert.cpp | 3 ++- firmware/baseband/proc_nfm_audio.cpp | 3 ++- firmware/baseband/proc_tpms.cpp | 3 ++- firmware/baseband/proc_wfm_audio.cpp | 3 ++- firmware/baseband/proc_wideband_spectrum.cpp | 3 ++- 10 files changed, 16 insertions(+), 36 deletions(-) delete mode 100755 firmware/baseband/main.cpp diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 832cb5d8..54010d73 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -98,7 +98,6 @@ set(CSRC # setting. set(CPPSRC baseband.cpp - main.cpp ${COMMON}/message_queue.cpp ${COMMON}/event.cpp event_m4.cpp diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp deleted file mode 100755 index cfd20dd4..00000000 --- a/firmware/baseband/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2014 Jared Boone, ShareBrained Technology, 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. - */ - -extern void run(); - -int main(void) { - run(); - return 0; -} diff --git a/firmware/baseband/proc_ais.cpp b/firmware/baseband/proc_ais.cpp index b5f95319..8cef6893 100644 --- a/firmware/baseband/proc_ais.cpp +++ b/firmware/baseband/proc_ais.cpp @@ -65,7 +65,8 @@ void AISProcessor::payload_handler( shared_memory.application_queue.push(message); } -void run() { +int main() { EventDispatcher event_dispatcher { std::make_unique() }; event_dispatcher.run(); + return 0; } diff --git a/firmware/baseband/proc_am_audio.cpp b/firmware/baseband/proc_am_audio.cpp index a35f0742..6444a9fe 100644 --- a/firmware/baseband/proc_am_audio.cpp +++ b/firmware/baseband/proc_am_audio.cpp @@ -108,7 +108,8 @@ void NarrowbandAMAudio::capture_config(const CaptureConfigMessage& message) { } } -void run() { +int main() { EventDispatcher event_dispatcher { std::make_unique() }; event_dispatcher.run(); + return 0; } diff --git a/firmware/baseband/proc_capture.cpp b/firmware/baseband/proc_capture.cpp index d68cae29..daa958d9 100644 --- a/firmware/baseband/proc_capture.cpp +++ b/firmware/baseband/proc_capture.cpp @@ -93,7 +93,8 @@ void CaptureProcessor::capture_config(const CaptureConfigMessage& message) { } } -void run() { +int main() { EventDispatcher event_dispatcher { std::make_unique() }; event_dispatcher.run(); + return 0; } diff --git a/firmware/baseband/proc_ert.cpp b/firmware/baseband/proc_ert.cpp index 124c141c..9997704b 100644 --- a/firmware/baseband/proc_ert.cpp +++ b/firmware/baseband/proc_ert.cpp @@ -104,7 +104,8 @@ void ERTProcessor::idm_handler( shared_memory.application_queue.push(message); } -void run() { +int main() { EventDispatcher event_dispatcher { std::make_unique() }; event_dispatcher.run(); + return 0; } diff --git a/firmware/baseband/proc_nfm_audio.cpp b/firmware/baseband/proc_nfm_audio.cpp index 18280b7c..7e72ddb0 100644 --- a/firmware/baseband/proc_nfm_audio.cpp +++ b/firmware/baseband/proc_nfm_audio.cpp @@ -96,7 +96,8 @@ void NarrowbandFMAudio::capture_config(const CaptureConfigMessage& message) { } } -void run() { +int main() { EventDispatcher event_dispatcher { std::make_unique() }; event_dispatcher.run(); + return 0; } diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index 61a23739..c9224c3c 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -58,7 +58,8 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) { } } -void run() { +int main() { EventDispatcher event_dispatcher { std::make_unique() }; event_dispatcher.run(); + return 0; } diff --git a/firmware/baseband/proc_wfm_audio.cpp b/firmware/baseband/proc_wfm_audio.cpp index 0bd8e068..2e553a7d 100644 --- a/firmware/baseband/proc_wfm_audio.cpp +++ b/firmware/baseband/proc_wfm_audio.cpp @@ -125,7 +125,8 @@ void WidebandFMAudio::capture_config(const CaptureConfigMessage& message) { } } -void run() { +int main() { EventDispatcher event_dispatcher { std::make_unique() }; event_dispatcher.run(); + return 0; } diff --git a/firmware/baseband/proc_wideband_spectrum.cpp b/firmware/baseband/proc_wideband_spectrum.cpp index c90fbad9..76d627c2 100644 --- a/firmware/baseband/proc_wideband_spectrum.cpp +++ b/firmware/baseband/proc_wideband_spectrum.cpp @@ -73,7 +73,8 @@ void WidebandSpectrum::on_message(const Message* const message) { } } -void run() { +int main() { EventDispatcher event_dispatcher { std::make_unique() }; event_dispatcher.run(); + return 0; }