diff --git a/firmware/common/hackrf-ui.c b/firmware/common/hackrf-ui.c index 8dd8715a..23974135 100644 --- a/firmware/common/hackrf-ui.c +++ b/firmware/common/hackrf-ui.c @@ -21,7 +21,7 @@ #include "hackrf-ui.h" -#include "ui_portapack.h" +#include "portapack.h" #include "ui_rad1o.h" #include @@ -60,7 +60,7 @@ static const hackrf_ui_t hackrf_ui_null = { &hackrf_ui_set_antenna_bias_null, }; -const hackrf_ui_t* portapack_detect(void) __attribute__((weak)); +const portapack_t* portapack_init(void) __attribute__((weak)); const hackrf_ui_t* rad1o_ui_setup(void) __attribute__((weak)); static const hackrf_ui_t* ui = NULL; @@ -69,8 +69,11 @@ const hackrf_ui_t* hackrf_ui(void) { /* Detect on first use. If no UI hardware is detected, use a stub function table. */ if( ui == NULL ) { #ifdef HACKRF_ONE - if( portapack_detect ) { - ui = portapack_detect(); + if( portapack_init ) { + const portapack_t* const portapack = portapack_init(); + if( portapack != NULL ) { + ui = portapack->hackrf_ui; + } } #endif #ifdef RAD1O diff --git a/firmware/common/portapack.c b/firmware/common/portapack.c new file mode 100644 index 00000000..4c4f3a9b --- /dev/null +++ b/firmware/common/portapack.c @@ -0,0 +1,109 @@ +/* + * Copyright 2018 Jared Boone + * + * This file is part of 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. + */ + +#include "portapack.h" +#include "hackrf_core.h" + +static bool jtag_pp_tck(const bool tms_value) { + gpio_write(jtag_cpld.gpio->gpio_pp_tms, tms_value); + + // 8 ns TMS/TDI to TCK setup + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + + gpio_set(jtag_cpld.gpio->gpio_tck); + + // 15 ns TCK to TMS/TDI hold time + // 20 ns TCK high time + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + + gpio_clear(jtag_cpld.gpio->gpio_tck); + + // 20 ns TCK low time + // 25 ns TCK falling edge to TDO valid + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + + return gpio_read(jtag_cpld.gpio->gpio_pp_tdo); +} + +static uint32_t jtag_pp_shift(const uint32_t tms_bits, const size_t count) { + uint32_t result = 0; + size_t bit_in_index = count - 1; + size_t bit_out_index = 0; + while(bit_out_index < count) { + const uint32_t tdo = jtag_pp_tck((tms_bits >> bit_in_index) & 1) & 1; + result |= (tdo << bit_out_index); + + bit_in_index--; + bit_out_index++; + } + + return result; +} + +static uint32_t jtag_pp_idcode(void) { + cpld_jtag_take(&jtag_cpld); + + /* TODO: Check if PortaPack TMS is floating or driven by an external device. */ + gpio_output(jtag_cpld.gpio->gpio_pp_tms); + + /* Test-Logic/Reset -> Run-Test/Idle -> Select-DR/Scan -> Capture-DR */ + jtag_pp_shift(0b11111010, 8); + + /* Shift-DR */ + const uint32_t idcode = jtag_pp_shift(0, 32); + + /* Exit1-DR -> Update-DR -> Run-Test/Idle -> ... -> Test-Logic/Reset */ + jtag_pp_shift(0b11011111, 8); + + cpld_jtag_release(&jtag_cpld); + + return idcode; +} + +static bool portapack_detect(void) { + return jtag_pp_idcode() == 0x020A50DD; +} + +extern const hackrf_ui_t portapack_hackrf_ui; + +const portapack_t portapack = { + &portapack_hackrf_ui, +}; + +const portapack_t* portapack_init(void) { + if( portapack_detect() ) { + return &portapack; + } else { + return NULL; + } +} \ No newline at end of file diff --git a/firmware/common/portapack.h b/firmware/common/portapack.h new file mode 100644 index 00000000..cd0a8f7a --- /dev/null +++ b/firmware/common/portapack.h @@ -0,0 +1,33 @@ +/* + * Copyright 2018 Jared Boone + * + * This file is part of 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. + */ + +#ifndef __PORTAPACK_H__ +#define __PORTAPACK_H__ + +#include "hackrf-ui.h" + +typedef struct { + const hackrf_ui_t* const hackrf_ui; +} portapack_t; + +const portapack_t* portapack_init(void); + +#endif/*__PORTAPACK_H__*/ diff --git a/firmware/common/ui_portapack.c b/firmware/common/ui_portapack.c index e8430af1..018a8cdb 100644 --- a/firmware/common/ui_portapack.c +++ b/firmware/common/ui_portapack.c @@ -455,74 +455,6 @@ static void portapack_lcd_wake() { portapack_lcd_display_on(); } -static bool jtag_pp_tck(const bool tms_value) { - gpio_write(jtag_cpld.gpio->gpio_pp_tms, tms_value); - - // 8 ns TMS/TDI to TCK setup - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - - gpio_set(jtag_cpld.gpio->gpio_tck); - - // 15 ns TCK to TMS/TDI hold time - // 20 ns TCK high time - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - - gpio_clear(jtag_cpld.gpio->gpio_tck); - - // 20 ns TCK low time - // 25 ns TCK falling edge to TDO valid - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - - return gpio_read(jtag_cpld.gpio->gpio_pp_tdo); -} - -static uint32_t jtag_pp_shift(const uint32_t tms_bits, const size_t count) { - uint32_t result = 0; - size_t bit_in_index = count - 1; - size_t bit_out_index = 0; - while(bit_out_index < count) { - const uint32_t tdo = jtag_pp_tck((tms_bits >> bit_in_index) & 1) & 1; - result |= (tdo << bit_out_index); - - bit_in_index--; - bit_out_index++; - } - - return result; -} - -static uint32_t jtag_pp_idcode() { - cpld_jtag_take(&jtag_cpld); - - /* TODO: Check if PortaPack TMS is floating or driven by an external device. */ - gpio_output(jtag_cpld.gpio->gpio_pp_tms); - - /* Test-Logic/Reset -> Run-Test/Idle -> Select-DR/Scan -> Capture-DR */ - jtag_pp_shift(0b11111010, 8); - - /* Shift-DR */ - const uint32_t idcode = jtag_pp_shift(0, 32); - - /* Exit1-DR -> Update-DR -> Run-Test/Idle -> ... -> Test-Logic/Reset */ - jtag_pp_shift(0b11011111, 8); - - cpld_jtag_release(&jtag_cpld); - - return idcode; -} - static void portapack_if_init() { portapack_data_mask_set(); portapack_data_write_high(0); @@ -1019,7 +951,7 @@ static void portapack_ui_set_antenna_bias(bool antenna_bias) { (void)antenna_bias; } -static const hackrf_ui_t portapack_ui = { +const hackrf_ui_t portapack_hackrf_ui = { &portapack_ui_init, &portapack_ui_set_frequency, &portapack_ui_set_sample_rate, @@ -1033,11 +965,3 @@ static const hackrf_ui_t portapack_ui = { &portapack_ui_set_filter, &portapack_ui_set_antenna_bias, }; - -const hackrf_ui_t* portapack_detect(void) { - if( jtag_pp_idcode() == 0x020A50DD ) { - return &portapack_ui; - } else { - return NULL; - } -} diff --git a/firmware/common/ui_portapack.h b/firmware/common/ui_portapack.h index 0d2fc58e..d4ddda18 100644 --- a/firmware/common/ui_portapack.h +++ b/firmware/common/ui_portapack.h @@ -56,6 +56,4 @@ typedef struct ui_font_t { size_t data_stride; } ui_font_t; -const hackrf_ui_t* portapack_detect(void); - #endif/*__UI_PORTAPACK_H__*/ diff --git a/firmware/hackrf_usb/CMakeLists.txt b/firmware/hackrf_usb/CMakeLists.txt index 271bf434..7e124b1f 100644 --- a/firmware/hackrf_usb/CMakeLists.txt +++ b/firmware/hackrf_usb/CMakeLists.txt @@ -66,6 +66,7 @@ set(SRC_M4 if(BOARD STREQUAL "HACKRF_ONE") SET(SRC_M4 ${SRC_M4} + "${PATH_HACKRF_FIRMWARE_COMMON}/portapack.c" "${PATH_HACKRF_FIRMWARE_COMMON}/ui_portapack.c" ) endif()