JTAG: Restore CPLD pin config functions, leave pins in pull-only state when not actively operating.
This commit is contained in:
@ -29,6 +29,75 @@ static refill_buffer_cb refill_buffer;
|
||||
static uint32_t xsvf_buffer_len, xsvf_pos;
|
||||
static unsigned char* xsvf_buffer;
|
||||
|
||||
void cpld_jtag_init(jtag_t* const jtag) {
|
||||
/* Initialize pin GPIOs in "released" state. */
|
||||
cpld_jtag_release(jtag);
|
||||
|
||||
/* TDI and TMS pull-ups are required in all JTAG-compliant devices.
|
||||
*
|
||||
* The HackRF CPLD is always present, so let the CPLD pull up its TDI and TMS.
|
||||
*
|
||||
* The PortaPack may not be present, so pull up the PortaPack TMS pin from the
|
||||
* microcontroller.
|
||||
*
|
||||
* TCK is recommended to be held low, so use microcontroller pull-down.
|
||||
*
|
||||
* TDO is undriven except when in Shift-IR or Shift-DR phases.
|
||||
* Use the microcontroller to pull down to keep from floating.
|
||||
*
|
||||
* LPC43xx pull-up and pull-down resistors are approximately 53K.
|
||||
*/
|
||||
#ifdef USER_INTERFACE_PORTAPACK
|
||||
scu_pinmux(SCU_PINMUX_PP_TMS, SCU_GPIO_PUP | SCU_CONF_FUNCTION0);
|
||||
scu_pinmux(SCU_PINMUX_PP_TDO, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||
#endif
|
||||
scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
|
||||
scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
|
||||
scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_PDN | SCU_CONF_FUNCTION4);
|
||||
scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||
}
|
||||
|
||||
void cpld_jtag_take(jtag_t* const jtag) {
|
||||
const jtag_gpio_t* const gpio = jtag->gpio;
|
||||
|
||||
#ifdef USER_INTERFACE_PORTAPACK
|
||||
/* Do not drive PortaPack-specific TMS pin initially, just to be cautious. */
|
||||
gpio_input(gpio->gpio_pp_tms);
|
||||
gpio_input(gpio->gpio_pp_tdo);
|
||||
#endif
|
||||
gpio_output(gpio->gpio_tms);
|
||||
gpio_output(gpio->gpio_tdi);
|
||||
gpio_output(gpio->gpio_tck);
|
||||
gpio_input(gpio->gpio_tdo);
|
||||
}
|
||||
|
||||
void cpld_jtag_release(jtag_t* const jtag) {
|
||||
const jtag_gpio_t* const gpio = jtag->gpio;
|
||||
|
||||
/* Make all pins inputs when JTAG interface not active.
|
||||
* Let the pull-ups/downs do the work.
|
||||
*/
|
||||
#ifdef USER_INTERFACE_PORTAPACK
|
||||
/* Do not drive PortaPack-specific pins, initially, just to be cautious. */
|
||||
gpio_input(gpio->gpio_pp_tms);
|
||||
gpio_input(gpio->gpio_pp_tdo);
|
||||
#endif
|
||||
gpio_input(gpio->gpio_tms);
|
||||
gpio_input(gpio->gpio_tdi);
|
||||
gpio_input(gpio->gpio_tck);
|
||||
gpio_input(gpio->gpio_tdo);
|
||||
|
||||
/* Set initial GPIO state to the voltages of the internal or external pull-ups/downs,
|
||||
* to avoid any glitches.
|
||||
*/
|
||||
#ifdef USER_INTERFACE_PORTAPACK
|
||||
gpio_set(gpio->gpio_pp_tms);
|
||||
#endif
|
||||
gpio_set(gpio->gpio_tms);
|
||||
gpio_set(gpio->gpio_tdi);
|
||||
gpio_clear(gpio->gpio_tck);
|
||||
}
|
||||
|
||||
/* return 0 if success else return error code see xsvfExecute() */
|
||||
int cpld_jtag_program(
|
||||
jtag_t* const jtag,
|
||||
@ -37,10 +106,12 @@ int cpld_jtag_program(
|
||||
refill_buffer_cb refill
|
||||
) {
|
||||
int error;
|
||||
cpld_jtag_take(jtag);
|
||||
xsvf_buffer = buffer;
|
||||
xsvf_buffer_len = buffer_length;
|
||||
refill_buffer = refill;
|
||||
error = xsvfExecute(jtag->gpio);
|
||||
cpld_jtag_release(jtag);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -43,6 +43,10 @@ typedef struct jtag_t {
|
||||
|
||||
typedef void (*refill_buffer_cb)(void);
|
||||
|
||||
void cpld_jtag_init(jtag_t* const jtag);
|
||||
void cpld_jtag_take(jtag_t* const jtag);
|
||||
void cpld_jtag_release(jtag_t* const jtag);
|
||||
|
||||
/* Return 0 if success else return error code see xsvfExecute() see micro.h.
|
||||
*
|
||||
* We expect the buffer to be initially full of data. After the entire
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "w25q80bv_target.h"
|
||||
#include "i2c_bus.h"
|
||||
#include "i2c_lpc.h"
|
||||
#include "cpld_jtag.h"
|
||||
#include <libopencm3/lpc43xx/cgu.h>
|
||||
#include <libopencm3/lpc43xx/ccu.h>
|
||||
#include <libopencm3/lpc43xx/scu.h>
|
||||
@ -758,49 +759,11 @@ void ssp1_set_mode_max5864(void)
|
||||
spi_bus_start(max5864.bus, &ssp_config_max5864);
|
||||
}
|
||||
|
||||
static void jtag_setup(void) {
|
||||
/* TDI and TMS pull-ups are required in all JTAG-compliant devices.
|
||||
* Therefore, do not pull up TDI and TMS on HackRF CPLD, which is always present.
|
||||
* HackRF TMS and TDI are dedicated, just drive instead of pulling up/down.
|
||||
* TCK is recommended to be held low.
|
||||
* TDO is undriven except when in Shift-IR or Shift-DR phases, so pull down to keep from floating.
|
||||
* Nail down other signals before causing any transitions on TCK, to prevent undesired
|
||||
* state changes.
|
||||
*/
|
||||
/* LPC43xx pull-up and pull-down resistors are approximately 53K. */
|
||||
#ifdef USER_INTERFACE_PORTAPACK
|
||||
gpio_set(jtag_gpio_cpld.gpio_pp_tms);
|
||||
#endif
|
||||
gpio_set(jtag_gpio_cpld.gpio_tms);
|
||||
gpio_set(jtag_gpio_cpld.gpio_tdi);
|
||||
gpio_clear(jtag_gpio_cpld.gpio_tck);
|
||||
|
||||
#ifdef USER_INTERFACE_PORTAPACK
|
||||
/* Do not drive PortaPack-specific pins, initially, just to be cautious. */
|
||||
gpio_input(jtag_gpio_cpld.gpio_pp_tms);
|
||||
gpio_input(jtag_gpio_cpld.gpio_pp_tdo);
|
||||
#endif
|
||||
gpio_output(jtag_gpio_cpld.gpio_tms);
|
||||
gpio_output(jtag_gpio_cpld.gpio_tdi);
|
||||
gpio_output(jtag_gpio_cpld.gpio_tck);
|
||||
gpio_input(jtag_gpio_cpld.gpio_tdo);
|
||||
|
||||
/* Configure CPLD JTAG pins */
|
||||
#ifdef USER_INTERFACE_PORTAPACK
|
||||
scu_pinmux(SCU_PINMUX_PP_TMS, SCU_GPIO_PUP | SCU_CONF_FUNCTION0);
|
||||
scu_pinmux(SCU_PINMUX_PP_TDO, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||
#endif
|
||||
scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
|
||||
scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
|
||||
scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_PDN | SCU_CONF_FUNCTION4);
|
||||
scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
|
||||
}
|
||||
|
||||
void pin_setup(void) {
|
||||
/* Configure all GPIO as Input (safe state) */
|
||||
gpio_init();
|
||||
|
||||
jtag_setup();
|
||||
cpld_jtag_init(&jtag_cpld);
|
||||
|
||||
/* Configure SCU Pin Mux as GPIO */
|
||||
scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_NOPULL);
|
||||
|
@ -503,6 +503,11 @@ static uint32_t jtag_pp_shift(const uint32_t tms_bits, const size_t count) {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -512,6 +517,8 @@ static uint32_t jtag_pp_idcode() {
|
||||
/* Exit1-DR -> Update-DR -> Run-Test/Idle -> ... -> Test-Logic/Reset */
|
||||
jtag_pp_shift(0b11011111, 8);
|
||||
|
||||
cpld_jtag_release(&jtag_cpld);
|
||||
|
||||
return idcode;
|
||||
}
|
||||
|
||||
@ -998,9 +1005,6 @@ static const hackrf_ui_t portapack_ui = {
|
||||
};
|
||||
|
||||
const hackrf_ui_t* portapack_detect(void) {
|
||||
/* TODO: Check if PortaPack TMS is floating or driven by an external device. */
|
||||
gpio_output(jtag_cpld.gpio->gpio_pp_tms);
|
||||
|
||||
if( jtag_pp_idcode() == 0x020A50DD ) {
|
||||
return &portapack_ui;
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user