PortaPack: Extract non-UI code into separate portapack.[ch] module.

I'll be adding some non-UI API functions to the top-level PortaPack structure.
This commit is contained in:
Jared Boone
2019-03-18 15:09:11 -07:00
parent 6bcd994e9e
commit 12bb516cc0
6 changed files with 151 additions and 83 deletions

View File

@ -21,7 +21,7 @@
#include "hackrf-ui.h"
#include "ui_portapack.h"
#include "portapack.h"
#include "ui_rad1o.h"
#include <stddef.h>
@ -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

109
firmware/common/portapack.c Normal file
View File

@ -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;
}
}

View File

@ -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__*/

View File

@ -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;
}
}

View File

@ -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__*/

View File

@ -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()