
通过其强大的PRUSS(可编程重新生成单元子系统)将我们的BBG转换为SWD编程器,以控制我们的位。 ![]() 硬件组件 BeagleBoard.org SeeedStudio BeagleBone Green × 1 效益 它是一体化的SWD程序员。您只需登录系统并调用OpenOCD即可。不需要在PC上安装任何专有软件。实施仅由自由软件完成。 # _# M' c; H8 S _+ g2 r' B用处 “THING”的任何应用都需要编程某种生成信号,PWM,串行通信等等。并且需要闪烁任何设备(带闪光灯)。 BBG-SWD是精确控制信号的一个具体例子,因此,它可以成为学习使用PRUSS控制信号的一个很好的起点。拥有值得信赖的闪存技术可以帮助每个人。 需要解决的问题 我设计了带有STM32F103的USB 32位“计算机”FST-01,这样我就可以安全地使用它进行加密计算(OpenPGP,SSH等)。为了刷这块板,我使用了ST-Link /V2或它兼容。但是,这是问题所在。我确定可靠地闪烁二进制文件吗? % s( f2 d) T6 [/ j! {% j" K我们如何可靠地安全地闪烁我们的板? 动机 在现代加密中,我们拥有足够强大的算法和实现。问题倾向于在运行那些加密计算的平台和能够进行这种计算的环境/过程中。这是我的观点,我开发了自己的解决方案,名为Gnuk Token。对于Gnuk Token,我设计了FST-01。 % V, n) S& ]/ A1 ] C然后,我遇到了上面的问题。在BBG-SWD之前,我没有具体的方法向制造商询问如何可靠地闪存FST-01。 # s( `' @. \0 G) g我想修复缺失的链接和/或可能最薄弱的环节,以实现最佳的实用加密计算。 , E e- l, m! i6 `固件的写入过程将是用户计算自由的缺失环节 为“安全设备”编写固件的过程可能是最薄弱的环节 如何解决问题 通过BBG作为一体化工具 通过使用PRUSS做正确的事情 对照 ST-Link / V2与PC上的软件工具 ST-Link / V2中的固件将是最薄弱的环节,除供应商之外的任何人都无法检查其正确性。专有工具对攻击也很弱。 % E; S5 p" N, _) o公共汽车盗版与PC上的软件工具 即使软件工具可能是自由软件,操作系统也是最薄弱的环节。 3 N* j' E$ L+ f% W$ E; ^巴士海盗与BBG 这是最好的做法(直到BBG-SWD)。 : J9 X1 {8 E$ o! E; `仅BBG,直接连接到目标板,即BBG-SWD 这是最终的解决方案。 如何 (0)BBG与Debian 内核应该是骨内核(而不是ti)才能使用uio_pruss模块。 " x6 }8 g" E& o5 c" K: nhttp://github.com/beagleboard/am335x_pru_package 必须已经在您的系统中。 (1)克隆BBG-SWD存储库 获取它并使用pasm构建PRU-SWD二进制文件。该指令在源代码中(pru-swd.p)。 : ?( N. s8 S$ H8 g" {- L: X(2)克隆OpenOCD存储库http://repo.or.cz/w/openocd.git 获取它并在BBG-SWD中应用补丁。使用--enable-bbg-swd的configure选项进行构建。 (3)将目标板连接到BBG 请参阅以下针脚。 (4)使用BBG-SWD驱动程序享受OpenOCD 未来的工作 应尽快添加SRST支持。 , I# W; K" L" k4 q如果吞吐量很重要,则应考虑排队系统(目前,它是简单的请求和响应)。 2016-03-26初始版本(版本0.01)。 % P* `" i% z0 K" r硬件方面,它很简单。我们只需将BBG中的三条(最多五条)线连接到目标板,即SWD-CLK,SWD-DIO和GND(另外,如果我们从BBG向目标板供电,则为3.3V,SRST用于可选的复位控制)。 软件方面,这是一个挑战。BBG上的芯片具有可编程实时子系统PRUSS,最适合精确位冲击的目的。但是,很难使用这个子系统。 1 P% d9 e. g# J/ E# M/ G- U我为这个项目选择“超级硬”作为该项目开发的技能水平。对于开发,它需要PRUSS,SWD和OpenOCD的知识。但是,仅供使用(没有开发工具),它将像其他JTAG / SWD程序员一样简单。“两个小时完成”意味着第一个实验将消耗两个小时左右,尝试这个项目(硬件的设置,项目的git克隆,构建一个尝试)。 我假设一个用户已经拥有一个带Debian的BBG。 Version 0.01 2016-03-26 NiibeYutaka Flying Stone Technology BeagleBoneGreen SWD BeagleBoneGreen SWD(BBG-SWD)是BeagleBoneGreen控制SWD协议的工具。 * e0 x5 x7 w: U: Q9 u: T; {; q初始版本的注意事项 PRUSS(可编程实时单元子系统)PRU-SWD上的程序已经完成。OpenOCD的BBG-SWD驱动程序是一个补丁: 0001-initial-patch-for-BBG-SWD.patch BBG-SWD驱动程序已准备就绪。要了解它的详细工作原理,请参阅OpenOCD的调试日志: flash-write-with-bbg-swd-20160326.log 未来的工作 由于FST-01没有引脚,SRST的复位引脚控制尚未实现。它很容易实现。 # Z" Y5 X O( I8 w$ s/ x目的 它再次为我们提供了对我们计算(自由)的控制。 ; c* \! r8 c( oSWD访问的引脚 SWD-DIO P8_11 SWD-CLK P8_12 SRST P8_15 Pinmux配置 # echo gpio>/sys/devices/platform/ocp/ocp: P8_11_pinmux/state # echo gpio >/sys/devices/platform/ocp/ocp: P8_12_pinmux/state # echo gpio_pu >/sys/devices/platform/ocp/ocp: P8_15_pinmux/state 方法论 它利用处理器上的PRUSS(可编程实时单元子系统),使SWD通信可靠,准确,快速。它假设使用PRUSSDRV用户空间库和UIO用户空间PRUSS驱动程序。我使用“骨内核”。 软件许可 程序pru-swd.p在GPLv3 +下发布。OpenOCD补丁在GPLv2 +下。 S }1 W8 O2 M: Y0 ^( ~8 C6 oOpenOCD补丁 补丁是: 0001-initial-patch-for-BBG-SWD.patch您可以通过配置BBG-SWD驱动程序 --enable-bbg-swd option. ./configure --enable-bbg-swd您可以使用以下配置来使用它: -------------------------- File: bbg-swd.cfginterface bbg-swdtransport select swd命令的invacatio是这样的: $ openocd -f bbg-swd.cfg -f target/stm32f1x.cfg以上是FST-01的情况。 请求 - 响应 格式: Request: 1-byte: CMD arg... Response: value...最后三位对CMD有效。 HALT 0 BLINK 1 GPIO_OUT 2 GPIO_IN 3 SIG_IDLE 4 SIG_GEN 5 READ_REG 6 WRITE_REG 7 HALT(): none BLINK(delay, counts, led-bit): none - SIG_IDLE(count): none submit idle(=LOW) for COUNT cycles,strobing SWD-CLK SIG_GEN(bit-len, data...): none submit signal pattern to SWD-DIO,strobing SWD-CLK READ_REG(cmd): parity-and-ack, value execute SWD read register transaction WRITE_REG(cmd,value): ack execute SWD write register transaction GPIO_OUT(bit, value): none control GPIO signal directly, output GPIO_IN(): value control GPIO signal directly, input & B T4 v) O3 j代码 From ee1d60eba7f9c35571241c1da4c8175c8b98daa1Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Tue, 22 Mar 2016 03:06:37 +0000 Subject: [PATCH 1/2] initial patch for BBG-SWD --- configure.ac | 13 ++ src/jtag/drivers/Makefile.am | 3 + src/jtag/drivers/bbg-swd.c | 444 +++++++++++++++++++++++++++++++++++++++++++ src/jtag/drivers/bbg-swd.h | 44 +++++ src/jtag/interfaces.c | 6 + 5 files changed, 510 insertions(+) create mode 100644 src/jtag/drivers/bbg-swd.c create mode 100644 src/jtag/drivers/bbg-swd.h # n$ \- K8 x) h3 {1 R, g! Xdiff --git a/configure.ac b/configure.ac index fb01e1b..d7f4ed9 100644 --- a/configure.ac +++ b/configure.ac @@ -527,6 +527,10 @@ AC_ARG_ENABLE([remote-bitbang], AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbangjtag driver]), [build_remote_bitbang=$enableval], [build_remote_bitbang=no]) 5 G6 @/ R1 _+ g- ~0 C0 w, T5 b+AC_ARG_ENABLE([bbg-swd], + AS_HELP_STRING([--enable-bbg-swd], [Enable building support for BBG-SWD.]), + [build_bbg_swd=$enableval], [build_bbg_swd=no]) + AC_MSG_CHECKING([whether to enable dummyminidriver]) if test $build_minidriver_dummy = yes; then if test $build_minidriver = yes; then @@ -818,6 +822,14 @@ if test $build_sysfsgpio = yes; then else AC_DEFINE([BUILD_SYSFSGPIO], [0], [0 if you don't want SysfsGPIO driver.]) fi + +if test $build_bbg_swd = yes; then + build_bbg_swd=yes + LIBS="$LIBS -lprussdrv" + AC_DEFINE([BUILD_BBG_SWD], [1], [1 if you want the BBG-SWD driver.]) +else + AC_DEFINE([BUILD_BBG_SWD], [0], [0 if you don't want the BBG-SWD driver.]) +fi #-- Deal with MingW/Cygwin FTD2XX issues . R: `2 F4 h+ U if test $is_win32 = yes; then @@ -1230,6 +1242,7 @@ AM_CONDITIONAL([IS_WIN32], [test $is_win32 = yes]) AM_CONDITIONAL([IS_DARWIN], [test $is_darwin = yes]) AM_CONDITIONAL([BITQ], [test $build_bitq = yes]) AM_CONDITIONAL([CMSIS_DAP], [test $use_hidapi = yes]) +AM_CONDITIONAL([BBG_SWD], [test $build_bbg_swd = yes]) AM_CONDITIONAL([MINIDRIVER], [test $build_minidriver = yes]) AM_CONDITIONAL([MINIDRIVER_DUMMY], [test $build_minidriver_dummy = yes]) diff --git a/src/jtag/drivers/Makefile.amb/src/jtag/drivers/Makefile.am index 2aaf8fd..4a87324 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -143,6 +143,9 @@ endif if CMSIS_DAP DRIVERFILES += cmsis_dap_usb.c endif +if BBG_SWD +DRIVERFILES += bbg-swd.c +endif # E$ A! Z E- O6 k' {1 t noinst_HEADERS = \ bitbang.h \ diff --git a/src/jtag/drivers/bbg-swd.cb/src/jtag/drivers/bbg-swd.c new file mode 100644 index 0000000..0363f45 --- /dev/null +++ b/src/jtag/drivers/bbg-swd.c @@ -0,0 +1,444 @@ +/*************************************************************************** + * Copyright (C) 2016 Flying StoneTechnology * + * Author: NIIBE Yutaka <gniibe@fsij.org> * + * * + * This program is free software; you can redistribute it and/ormodify * + * it under the terms of the GNU General Public License as publishedby * + * the Free Software Foundation; either version 2 of the License, 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <jtag/interface.h> +#include <jtag/commands.h> +#include <jtag/swd.h> + +#include <prussdrv.h> +#include <pruss_intc_mapping.h> + +#define PRU_NUM 0 + +extern struct jtag_interface *jtag_interface; +static void bbg_swd_write_reg(uint8_t cmd, uint32_t value,uint32_t ap_delay_clk); +static int bbg_swd_switch_seq(enum swd_special_seq seq); + +static void pru_request_cmd(uint32_t *p) +{ + /* Wakeup the PRU0 which sleeps. */ + prussdrv_pru_send_event(ARM_PRU0_INTERRUPT); + + /* Wait PRU0 response. */ + prussdrv_pru_wait_event(PRU_EVTOUT_0); + prussdrv_pru_clear_event(PRU_EVTOUT_0,PRU0_ARM_INTERRUPT); + if ((p[0] & 0xff) == 4 || (p[0] & 0xff) == 5 || (p[0] & 0xff) == 7) + LOG_DEBUG("BBD-SWD: command execution (%08x:%08x)", p[0], p[1]); + else + LOG_DEBUG("BBD-SWD: command execution (%08x)", p[0]); +} + +static int queued_retval; + +#define PRU_SWD_PROGRAM_PATH PKGDATADIR "/bbg-swd/pru-swd.bin" + +static uint32_t *pru_data_ram; +static tpruss_intc_initdata pruss_intc_initdata =PRUSS_INTC_INITDATA; + +static int bbg_swd_open(void) +{ + intr; + + LOG_DEBUG("bbg_swd_init"); + + /* Initialize the PRUSS driver. */ + prussdrv_init(); + + /* Open PRU interrupt to Host. */ + r= prussdrv_open(PRU_EVTOUT_0); + if (r < 0) { + LOG_ERROR("prussdrv_open open failed: %d", r); + return ERROR_FAIL; + } + + /* Initialize PRU interrupt controller. */ + prussdrv_pruintc_init(&pruss_intc_initdata); + + /* Initialize PRU memory access from Host. */ + r= prussdrv_map_prumem(PRUSS0_PRU0_DATARAM, (void **)&pru_data_ram); + if (r < 0) { + prussdrv_exit(); + LOG_ERROR("prussdrv_map_prumem failed: %d", r); + return ERROR_FAIL; + } + + /* Execute example on PRU */ + LOG_DEBUG("Executing PRU-SWU program on PRUSS"); + r= prussdrv_exec_program(PRU_NUM, PRU_SWD_PROGRAM_PATH); + if (r < 0) { + prussdrv_exit(); + LOG_ERROR("prussdrv_exec_program failed: %d", r); + return ERROR_FAIL; + } + return ERROR_OK; +} + + +static int bbg_swd_close(void) +{ + /* Disable PRU. */ + prussdrv_pru_disable(PRU_NUM); + prussdrv_exit(); + return ERROR_OK; +} + + +static int bbg_swd_gpio_srst(int on) +{ + /* XXX: not yet implemented */ + return ERROR_OK; +} + +static bool swd_mode; + +static int bbg_swd_interface_init(void) +{ + intretval; + enum reset_typesjtag_reset_config = jtag_get_reset_config(); + + if (swd_mode) { + retval= bbg_swd_open(); + if (retval != ERROR_OK) + return retval; + } + + if (jtag_reset_config& RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config& RESET_SRST_NO_GATING) { + retval= bbg_swd_gpio_srst(0); + if (retval != ERROR_OK) + return ERROR_FAIL; + LOG_INFO("Connecting under reset"); + } + } + + LOG_INFO("BBG-SWD: Interface ready"); + + return ERROR_OK; +} + +static int bbg_swd_interface_quit(void) +{ + bbg_swd_close(); + return ERROR_OK; +} + +static int bbg_swd_swd_init(void) +{ + swd_mode= true; + return ERROR_OK; +} + +enum { + CMD_HALT= 0, + CMD_BLINK, + CMD_GPIO_OUT, + CMD_GPIO_IN, + CMD_SIG_IDLE, + CMD_SIG_GEN, + CMD_READ_REG, + CMD_WRITE_REG +}; + +#define BBG_SWS_RESULT 16 + +/* + * Signal patterns are defined in: + * ARMDebug Interface Architecture Specification (ADI) + */ +static const uint8_t seq_jtag_to_swd[] = { 0xde, 0xf9 }; +static const int seq_jtag_to_swd_len = 16; +static const uint8_t seq_swd_to_seq[] = { 0x3c, 0xe7 }; +static const int seq_swd_to_jtag_len = 16; + +static void bbg_swd_idle(int count) +{ + pru_data_ram[0] = CMD_SIG_IDLE; + pru_data_ram[1] = count; + pru_request_cmd(pru_data_ram); +} + +static int bbg_swd_switch_seq(enum swd_special_seq seq) +{ + LOG_DEBUG("bbg_swd_switch_seq"); + + switch (seq) { + case LINE_RESET: + LOG_DEBUG("SWD line reset"); + pru_data_ram[0] = CMD_SIG_GEN |(swd_seq_line_reset_len << 8); + memcpy(&pru_data_ram[1], swd_seq_line_reset, swd_seq_line_reset_len); + pru_request_cmd(pru_data_ram); + break; + case JTAG_TO_SWD: + LOG_DEBUG("JTAG-to-SWD"); + pru_data_ram[0] = CMD_SIG_GEN |(swd_seq_jtag_to_swd_len << 8); + memcpy(&pru_data_ram[1], swd_seq_jtag_to_swd, swd_seq_jtag_to_swd_len); + pru_request_cmd(pru_data_ram); + bbg_swd_idle(8); + break; + case SWD_TO_JTAG: + LOG_DEBUG("JTAG-to-SWD"); + pru_data_ram[0] = CMD_SIG_GEN |(swd_seq_swd_to_jtag_len << 8); + memcpy(&pru_data_ram[1], swd_seq_swd_to_jtag, swd_seq_swd_to_jtag_len); + pru_request_cmd(pru_data_ram); + break; + default: + LOG_ERROR("Sequence %d not supported", seq); + return ERROR_FAIL; + } + + return ERROR_OK; +} + +static void bbg_swd_clear_sticky_errors(void) +{ + bbg_swd_write_reg(swd_cmd(false, false, DP_ABORT), + STKCMPCLR| STKERRCLR | WDERRCLR | ORUNERRCLR, 0); +} + + +static void bbg_swd_read_reg(uint8_t cmd, uint32_t *value,uint32_t ap_delay_clk) +{ + LOG_DEBUG("bbg_swd_read_reg"); + assert(cmd& SWD_CMD_RnW); + assert(ap_delay_clk< 256); + + if (queued_retval !=ERROR_OK) { + LOG_DEBUG("Skip bbg_swd_read_reg becausequeued_retval=%d", queued_retval); + return; + } + + for (;;) { + intack; + intparity; + uint32_tdata; + uint32_tdelay = 0; + + if (cmd &SWD_CMD_APnDP) + delay= ap_delay_clk; + + cmd|= 0x81; + pru_data_ram[0] = CMD_READ_REG |(cmd << 8) | (delay<< 24); + pru_request_cmd(pru_data_ram); + ack= pru_data_ram[BBG_SWS_RESULT] & 0x07; + parity= (pru_data_ram[BBG_SWS_RESULT] & 0x80000000) != 0; + data= pru_data_ram[BBG_SWS_RESULT+1]; + + LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, + ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack ==SWD_ACK_FAULT ? "FAULT" : "JUNK", + cmd & SWD_CMD_APnDP ? "AP" : "DP", + cmd & SWD_CMD_RnW ? "read" : "write", + (cmd & SWD_CMD_A32) >> 1, + data); + + switch (ack) { + case SWD_ACK_OK: + if (parity !=parity_u32(data)) { + LOG_DEBUG("Wrong parity detected (%d)", parity); + queued_retval= ERROR_FAIL; + return; + } + if (value) + *value= data; + return; + case SWD_ACK_WAIT: + LOG_DEBUG("SWD_ACK_WAIT"); + bbg_swd_clear_sticky_errors(); + break; + case SWD_ACK_FAULT: + LOG_DEBUG("SWD_ACK_FAULT"); + queued_retval= ack; + return; + default: + LOG_DEBUG("No valid acknowledge: ack=%d", ack); + queued_retval= ack; + return; + } + } +} + +static void bbg_swd_write_reg(uint8_t cmd, uint32_t value,uint32_t ap_delay_clk) +{ + LOG_DEBUG("bbg_swd_write_reg"); + assert(!(cmd& SWD_CMD_RnW)); + assert(ap_delay_clk< 256); + + if (queued_retval !=ERROR_OK) { + LOG_DEBUG("Skip bbg_swd_write_reg becausequeued_retval=%d", queued_retval); + return; + } + + for (;;) { + intack; + intparity = parity_u32(value); + uint32_tdelay = 0; + + if (cmd &SWD_CMD_APnDP) + delay= ap_delay_clk; + + cmd|= 0x81; + pru_data_ram[0] = CMD_WRITE_REG |(cmd << 8) | (parity<< 16) | (delay<< 24); + pru_data_ram[1] = value; + pru_request_cmd(pru_data_ram); + ack= pru_data_ram[BBG_SWS_RESULT] & 0x07; + + LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, + ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack ==SWD_ACK_FAULT ? "FAULT" : "JUNK", + cmd & SWD_CMD_APnDP ? "AP" : "DP", + cmd & SWD_CMD_RnW ? "read" : "write", + (cmd & SWD_CMD_A32) >> 1, + value); + + switch (ack) { + case SWD_ACK_OK: + return; + case SWD_ACK_WAIT: + LOG_DEBUG("SWD_ACK_WAIT"); + bbg_swd_clear_sticky_errors(); + break; + case SWD_ACK_FAULT: + LOG_DEBUG("SWD_ACK_FAULT"); + queued_retval= ack; + return; + default: + LOG_DEBUG("No valid acknowledge: ack=%d", ack); + queued_retval= ack; + return; + } + } +} + +static int bbg_swd_run_queue(void) +{ + intretval; + + LOG_DEBUG("bbg_swd_run_queue"); + bbg_swd_idle(8); + retval= queued_retval; + queued_retval= ERROR_OK; + LOG_DEBUG("SWD queue return value: %02x", retval); + return retval; +} + +const struct swd_driver bbg_swd = { + .init= bbg_swd_swd_init, + .switch_seq= bbg_swd_switch_seq, + .read_reg= bbg_swd_read_reg, + .write_reg= bbg_swd_write_reg, + .run= bbg_swd_run_queue, +}; + + +static const char * const bbg_swd_transport[] = { "swd", NULL }; + + +COMMAND_HANDLER(bbg_swd_handle_hello_command) +{ + puts("Hello!"); + return ERROR_OK; +} + +static const struct command_registration bbg_swd_command_handlers[] = { + { + .name= "bbg_swd_hello", + .handler= &bbg_swd_handle_hello_command, + .mode= COMMAND_CONFIG, + .help= "hello command for BBG-SWD", + .usage= "<cmd>", + }, + COMMAND_REGISTRATION_DONE +}; + +static void bbg_swd_execute_reset(struct jtag_command *cmd) +{ + bbg_swd_gpio_srst(cmd->cmd.reset->srst? 0: 1); +} + +static void bbg_swd_execute_sleep(struct jtag_command *cmd) +{ + jtag_sleep(cmd->cmd.sleep->us); +} + +static void bbg_swd_execute_command(struct jtag_command *cmd) +{ + switch (cmd->type) { + case JTAG_RESET: + bbg_swd_execute_reset(cmd); + break; + case JTAG_SLEEP: + bbg_swd_execute_sleep(cmd); + break; + default: + LOG_ERROR("BUG: unknown JTAG command type encountered"); + exit(-1); + } +} + +static int bbg_swd_interface_execute_queue(void) +{ + struct jtag_command *cmd =jtag_command_queue; + + while (cmd != NULL) { + bbg_swd_execute_command(cmd); + cmd= cmd->next; + } + + return ERROR_OK; +} + +static int bbg_swd_interface_speed(int speed) +{ + return ERROR_OK; +} + +static int bbg_swd_interface_speed_div(int speed, int *khz) +{ + *khz= speed; + return ERROR_OK; +} + +static int bbg_swd_interface_khz(int khz, int *jtag_speed) +{ + *jtag_speed= khz; + return ERROR_OK; +} + +struct jtag_interface bbg_swd_interface = { + .name= "bbg-swd", + .commands= bbg_swd_command_handlers, + .swd= &bbg_swd, + .transports= bbg_swd_transport, + + .execute_queue= bbg_swd_interface_execute_queue, + .speed= bbg_swd_interface_speed, + .speed_div= bbg_swd_interface_speed_div, + .khz= bbg_swd_interface_khz, + + .init= bbg_swd_interface_init, + .quit= bbg_swd_interface_quit, +}; +/* + * Local Variables: + * c-file-style: "linux" + * End: + */ diff --git a/src/jtag/drivers/bbg-swd.hb/src/jtag/drivers/bbg-swd.h new file mode 100644 index 0000000..f0c92b3 --- /dev/null +++ b/src/jtag/drivers/bbg-swd.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2016 Flying StoneTechnology * + * Author: NIIBE Yutaka <gniibe@fsij.org> * + * * + * This program is free software; you can redistribute it and/ormodify * + * it under the terms of the GNU General Public License as publishedby * + * the Free Software Foundation; either version 2 of the License, 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#ifndef BBG_SWD_H +#define BBG_SWD_H + +#include <jtag/swd.h> + +struct bbg_swd_interface { + /* low level callbacks (for bbg_swd) + */ + int(*read)(void); + void(*write)(int tck, int tms, int tdi); + void(*reset)(int trst, int srst); + void(*blink)(int on); + int(*swdio_read)(void); + void(*swdio_drive)(bool on); +}; + +const struct swd_driver bbg_swd_swd; + +int bbg_swd_execute_queue(void); + +extern struct jtag_interface bbg_swd_interface; +int bbg_swd_swd_switch_seq(enum swd_special_seq seq); + +#endif /* BBG_SWD_H */ diff --git a/src/jtag/interfaces.cb/src/jtag/interfaces.c index 62c5d45..b3fb2bd 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -131,6 +131,9 @@ extern struct jtag_interface bcm2835gpio_interface; #if BUILD_CMSIS_DAP == 1 extern struct jtag_interfacecmsis_dap_interface; #endif +#if BUILD_BBG_SWD== 1 +extern struct jtag_interface bbg_swd_interface; +#endif #endif /* standard drivers */ /** @@ -230,6 +233,9 @@ struct jtag_interface*jtag_interfaces[] = { #ifBUILD_CMSIS_DAP == 1 &cmsis_dap_interface, #endif +#if BUILD_BBG_SWD == 1 + &bbg_swd_interface, +#endif #endif /* standard drivers */ NULL, }; -- 2.1.4 $ d- `" s+ M! U2 s9 C3 X, B) K) S |