Version 0.03. release/0.03
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 22 Mar 2018 09:07:02 +0000 (18:07 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 22 Mar 2018 09:07:02 +0000 (18:07 +0900)
0001-jtag-drivers-bbg-swd-New-SWD-driver.patch [new file with mode: 0644]
README

diff --git a/0001-jtag-drivers-bbg-swd-New-SWD-driver.patch b/0001-jtag-drivers-bbg-swd-New-SWD-driver.patch
new file mode 100644 (file)
index 0000000..a71033e
--- /dev/null
@@ -0,0 +1,573 @@
+From ca085bb0dab3a732e71b4ca5e87757cd8351508f Mon Sep 17 00:00:00 2001
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Wed, 14 Mar 2018 17:56:39 +0900
+Subject: [PATCH] jtag: drivers: bbg-swd: New SWD driver
+
+---
+ configure.ac                 |  23 ++-
+ src/jtag/drivers/Makefile.am |   3 +
+ src/jtag/drivers/bbg-swd.c   | 399 +++++++++++++++++++++++++++++++++++++++++++
+ src/jtag/drivers/bbg-swd.h   |  44 +++++
+ src/jtag/interfaces.c        |   6 +
+ 5 files changed, 474 insertions(+), 1 deletion(-)
+ create mode 100644 src/jtag/drivers/bbg-swd.c
+ create mode 100644 src/jtag/drivers/bbg-swd.h
+
+diff --git a/configure.ac b/configure.ac
+index 6949402a..282f6e60 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -137,6 +137,9 @@ m4_define([LIBFTDI_ADAPTERS],
+ m4_define([LIBJAYLINK_ADAPTERS],
+       [[[jlink], [SEGGER J-Link Programmer], [JLINK]]])
++m4_define([BBG_ADAPTERS],
++      [[[bbg_swd], [PocketBeagle PRU Programmer], [BBG_SWD]]])
++
+ AC_ARG_ENABLE([doxygen-html],
+   AS_HELP_STRING([--disable-doxygen-html],
+@@ -355,6 +358,10 @@ AC_ARG_ENABLE([remote-bitbang],
+   AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbang jtag driver]),
+   [build_remote_bitbang=$enableval], [build_remote_bitbang=no])
++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 dummy minidriver])
+ AS_IF([test "x$build_minidriver_dummy" = "xyes"], [
+   AS_IF([test "x$build_minidriver" = "xyes"], [
+@@ -572,6 +579,19 @@ AS_IF([test "x$build_sysfsgpio" = "xyes"], [
+   AC_DEFINE([BUILD_SYSFSGPIO], [0], [0 if you don't want SysfsGPIO driver.])
+ ])
++AS_IF([test "x$build_bbg_swd" = "xyes"], [
++  build_bbg_swd=yes
++  AC_SEARCH_LIBS([prussdrv_init], [prussdrv], [], [
++    AC_MSG_FAILURE([[
++*** Could not find the prussdrv library.
++*** Please install it from am335x_pru_package.
++]])
++  ])
++  AC_DEFINE([BUILD_BBG_SWD], [1], [1 if you want the BBG-SWD driver.])
++], [
++  AC_DEFINE([BUILD_BBG_SWD], [0], [0 if you don't want the BBG-SWD driver.])
++])
++
+ PKG_CHECK_MODULES([LIBUSB1], [libusb-1.0], [
+       use_libusb1=yes
+       AC_DEFINE([HAVE_LIBUSB1], [1], [Define if you have libusb-1.x])
+@@ -679,6 +699,7 @@ AM_CONDITIONAL([OOCD_TRACE], [test "x$build_oocd_trace" = "xyes"])
+ AM_CONDITIONAL([REMOTE_BITBANG], [test "x$build_remote_bitbang" = "xyes"])
+ AM_CONDITIONAL([BUSPIRATE], [test "x$build_buspirate" = "xyes"])
+ AM_CONDITIONAL([SYSFSGPIO], [test "x$build_sysfsgpio" = "xyes"])
++AM_CONDITIONAL([BBG_SWD], [test "x$build_bbg_swd" = "xyes"])
+ AM_CONDITIONAL([USE_LIBUSB0], [test "x$use_libusb0" = "xyes"])
+ AM_CONDITIONAL([USE_LIBUSB1], [test "x$use_libusb1" = "xyes"])
+ AM_CONDITIONAL([IS_CYGWIN], [test "x$is_cygwin" = "xyes"])
+@@ -756,7 +777,7 @@ echo
+ echo OpenOCD configuration summary
+ echo --------------------------------------------------
+ m4_foreach([adapter], [USB1_ADAPTERS, USB_ADAPTERS, USB0_ADAPTERS,
+-      HIDAPI_ADAPTERS, LIBFTDI_ADAPTERS, LIBJAYLINK_ADAPTERS],
++      HIDAPI_ADAPTERS, LIBFTDI_ADAPTERS, LIBJAYLINK_ADAPTERS, BBG_ADAPTERS],
+       [s=m4_format(["%-40s"], ADAPTER_DESC([adapter]))
+       AS_CASE([$ADAPTER_VAR([adapter])],
+               [auto], [
+diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am
+index e4114126..cd7de739 100644
+--- a/src/jtag/drivers/Makefile.am
++++ b/src/jtag/drivers/Makefile.am
+@@ -152,6 +152,9 @@ endif
+ if CMSIS_DAP
+ DRIVERFILES += %D%/cmsis_dap_usb.c
+ endif
++if BBG_SWD
++DRIVERFILES += %D%/bbg-swd.c
++endif
+ DRIVERHEADERS = \
+       %D%/bitbang.h \
+diff --git a/src/jtag/drivers/bbg-swd.c b/src/jtag/drivers/bbg-swd.c
+new file mode 100644
+index 00000000..2a4fa812
+--- /dev/null
++++ b/src/jtag/drivers/bbg-swd.c
+@@ -0,0 +1,399 @@
++/***************************************************************************
++ *   Copyright (C) 2016  Flying Stone Technology                           *
++ *   Author: NIIBE Yutaka <gniibe@fsij.org>                                *
++ *                                                                         *
++ *   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 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)
++{
++      int r;
++
++      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 void bbg_swd_gpio_srst(int on);
++
++static bool swd_mode;
++
++static int bbg_swd_interface_init(void)
++{
++      int retval;
++      enum reset_types jtag_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) {
++                      bbg_swd_gpio_srst(0);
++                      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
++
++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 void bbg_swd_gpio_srst(int signal)
++{
++      pru_data_ram[0] = CMD_GPIO_OUT;
++      pru_data_ram[1] = (1 << 15);
++      pru_data_ram[2] = signal ? 1 : 0;
++      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+7)/8);
++              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+7)/8);
++              pru_request_cmd(pru_data_ram);
++              bbg_swd_idle(8);
++              break;
++      case SWD_TO_JTAG:
++              LOG_DEBUG("SWD-to-JTAG");
++              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+7)/8);
++              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_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
++{
++      int ack;
++      int parity;
++      uint32_t data;
++      uint32_t delay = 0;
++
++      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 because queued_retval=%d", queued_retval);
++              return;
++      }
++
++      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);
++
++      if (ack != SWD_ACK_OK) {
++              queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;
++      } else if (parity != parity_u32(data)) {
++              LOG_DEBUG("Wrong parity detected (%d)", parity);
++              queued_retval = ERROR_FAIL;
++      } else if (value) {
++              *value = data;
++              queued_retval = ERROR_OK;
++      }
++}
++
++static void bbg_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
++{
++      int ack;
++      int parity = parity_u32(value);
++      uint32_t delay = 0;
++
++      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 because queued_retval=%d", queued_retval);
++              return;
++      }
++
++      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);
++
++      if (ack != SWD_ACK_OK)
++              queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;
++}
++
++static int bbg_swd_run_queue(void)
++{
++      int retval;
++
++      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.h b/src/jtag/drivers/bbg-swd.h
+new file mode 100644
+index 00000000..f0c92b3f
+--- /dev/null
++++ b/src/jtag/drivers/bbg-swd.h
+@@ -0,0 +1,44 @@
++/***************************************************************************
++ *   Copyright (C) 2016  Flying Stone Technology                           *
++ *   Author: NIIBE Yutaka <gniibe@fsij.org>                                *
++ *                                                                         *
++ *   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 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.c b/src/jtag/interfaces.c
+index ad656a84..cbd08c79 100644
+--- a/src/jtag/interfaces.c
++++ b/src/jtag/interfaces.c
+@@ -123,6 +123,9 @@ extern struct jtag_interface bcm2835gpio_interface;
+ #if BUILD_CMSIS_DAP == 1
+ extern struct jtag_interface cmsis_dap_interface;
+ #endif
++#if BUILD_BBG_SWD == 1
++extern struct jtag_interface bbg_swd_interface;
++#endif
+ #endif /* standard drivers */
+ /**
+@@ -216,6 +219,9 @@ struct jtag_interface *jtag_interfaces[] = {
+ #if BUILD_CMSIS_DAP == 1
+               &cmsis_dap_interface,
+ #endif
++#if BUILD_BBG_SWD == 1
++              &bbg_swd_interface,
++#endif
+ #endif /* standard drivers */
+               NULL,
+       };
+-- 
+2.11.0
+
diff --git a/README b/README
index eb0e057..af7f627 100644 (file)
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
 BeagleBoneGreen SWD - a practical tool for computing freedom
 
-                                                       Version 0.02
-                                                         2016-05-06
+                                                       Version 0.03
+                                                         2018-03-22
                                                        Niibe Yutaka
                                             Flying Stone Technology
 
@@ -9,24 +9,25 @@ BeagleBoneGreen SWD
 ===================
 
 BeagleBoneGreen SWD (BBG-SWD) is a tool to control SWD protocol by
-BeagleBoneGreen.
+BeagleBoneGreen or PocketBeagle.
 
 
-Note for release 0.02
+Note for release 0.03
 =====================
 
-The program on PRUSS (Programmable Realtime Unit SubSytem), PRU-SWD,
-was updated to support pin control of SRST.
+The patch is for OpenOCD 0.10.0.
 
 The BBG-SWD driver for OpenOCD is by a patch:
 
-       0001-Add-new-SWD-driver-bbg-swd.patch
+       0001-jtag-drivers-bbg-swd-New-SWD-driver.patch
 
 The BBG-SWD driver is ready for use.  It is tested with FST-01 (STM32F103),
 FSM-55 (STM32F030) and prototype of FS-BB48 (KL27Z256).
 
 Use of "bone-kernel" is assumed for UIO user space PRUSS driver.
 
+It is also tested with PocketBeagle.
+
 
 Future Works
 ============
@@ -44,6 +45,9 @@ It gives (back) us the control for our computing (freedom), again.
 Pins for SWD access
 ===================
 
+For BBG
+-------
+
 SWD-DIO                P8_11
 SWD-CLK                P8_12
 SRST           P8_15
@@ -55,6 +59,23 @@ Pinmux Configuration
     # echo gpio_pu >/sys/devices/platform/ocp/ocp:P8_15_pinmux/state
 
 
+For PocketBeagle
+----------------
+
+SWD-DIO                P2_33
+SWD-CLK                P2_24
+SRST           P2_18
+3V3            P2_23
+GND            P2_21
+
+Pinmux Configuration
+
+    # echo gpio >/sys/devices/platform/ocp/ocp:P2_24_pinmux/state
+    # echo gpio >/sys/devices/platform/ocp/ocp:P2_33_pinmux/state
+    # echo gpio_pu >/sys/devices/platform/ocp/ocp:P2_18_pinmux/state
+
+
+
 The methodology
 ===============