--- /dev/null
+Support for remote bitbang SWD access using openOCD
+
+Copyright 2015 Cyprien Laplace <cyprien@cypou.net>
+
+/* ****************************************************************************
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+
+This app provides an SWD bridge for remote bitbang SWD access using openocd.
+This allows remote debugging using gdb.
+
+Warning: this is a work in progress.
+We tried a few gdb commands with success (bt, cont, up, info registers, ...),
+and some with less success (display, hbreak, watch).
+We also need test at higher UART speed.
+
+
+----------------
+Get openOCD with the SWD bitbang patch from this git repository:
+ http://gitweb.cypou.net/?p=openocd-code.git;a=shortlog;h=refs/heads/bitbang
+ git clone http://gitweb.cypou.net/git/openocd-code.git
+ git checkout -b bitbang origin/bitbang
+
+----------------
+Compile using:
+ ./bootstrap
+ ./configure --enable-remote-bitbang
+ make
+
+----------------
+Install:
+At your convenience, either :
+ make install
+Or :
+ dest_dir="../openocd-use"
+ mkdir $dest_dir
+ cp -r src/openocd tcl/target/ tcl/*.tcl $dest_dir
+ cd $dest_dir
+
+----------------
+Connection to the remote target :
+You must connect P0_23 and P0_24 from this board to swdio and swdclk on target board.
+Local Remote
+ P0_23 ---> swdio
+ P0_24 ---> swdclk
+ GND ---> GND
+You of course need to connect the module running the remote_bitbang app to the
+host which will run openOCD, and provide power to the target, either from the
+module running this app or from it's own power source.
+
+----------------
+Start OpenOCD with (change the /dev/ttyXXX and target/XXX according to your needs,
+and add "./" if you chose the second option for installation):
+ openocd -c "interface remote_bitbang; remote_bitbang_host /dev/ttyUSB0; transport select swd; gdb_port 3333; telnet_port 4444" -f target/lpc12xx.cfg
+
+----------------
+Run GDB for the app you want to debug (with the right architecture, certainly
+arm-none-eabi-gdb, but adapt to your needs). Best is to run from the root
+directory of the modules sources. For example:
+ arm-none-eabi-gdb -tui apps/base/i2c_temp/i2c_temp.elf
+ (gdb) target remote localhost:3333
+
+And use GDB as usual. (Ctrl-C may help you stop the running app on your target).
+
+
+
--- /dev/null
+/****************************************************************************
+ * apps/cyp/remote_bitbang/main.c
+ *
+ * Support for remote bitbang SWD access using openOCD
+ *
+ * Copyright 2015 Cyprien Laplace <cyprien@cypou.net>
+ *
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+
+/*
+ * This app provides an SWD bridge for remote bitbang SWD access using openocd.
+ * This allows remote debugging using gdb.
+ *
+ * Refer to README file for usage informations.
+ */
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "lib/stdio.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "extdrv/status_led.h"
+
+
+#define SELECTED_FREQ FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+ /* UART 0 */
+ { LPC_UART0_RX_PIO_0_1, LPC_IO_DIGITAL },
+ { LPC_UART0_TX_PIO_0_2, LPC_IO_DIGITAL },
+ { LPC_UART1_RX_PIO_0_8, LPC_IO_DIGITAL },
+ { LPC_UART1_TX_PIO_0_9, LPC_IO_DIGITAL },
+ ARRAY_LAST_PIO,
+};
+
+
+const struct pio led_green = LPC_GPIO_0_28;
+const struct pio led_red = LPC_GPIO_0_29;
+#define LED_RED (1 << led_red.pin)
+#define LED_GREEN (1 << led_green.pin)
+
+/* These two MUST be on the same port */
+const struct pio swd_io = LPC_GPIO_0_23;
+const struct pio swd_clk = LPC_GPIO_0_24;
+#define SWD_IO (1 << swd_io.pin)
+#define SWD_CLK (1 << swd_clk.pin)
+
+void system_init()
+{
+ /* Stop the watchdog */
+ stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+ /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+ * it back on if called after system_init() */
+ system_brown_out_detection_config(0);
+ system_set_default_power_state();
+ clock_config(SELECTED_FREQ);
+ set_pins(common_pins);
+ gpio_on();
+ status_led_config(&led_green, &led_red);
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+ serial_write(0, name, len);
+ /* Wait for end of Tx */
+ serial_flush(1);
+ /* FIXME : Perform soft reset of the micro-controller ! */
+ while (1);
+}
+
+static void uart_cb(uint8_t data)
+{
+ char in;
+ struct lpc_gpio* gpio_io = LPC_GPIO_REGS(swd_io.port);
+ struct lpc_gpio* gpio_red = LPC_GPIO_REGS(led_red.port);
+ struct lpc_gpio* gpio_green = LPC_GPIO_REGS(led_red.port);
+
+ if (data >= '0' && data <= '7') {
+ uint32_t val = 0;
+ data -= '0';
+ if (data & 1)
+ val |= SWD_IO;
+ if (data & 4)
+ val |= SWD_CLK;
+ gpio_io->out = val;
+ } else switch(data) {
+ case 'i':
+ gpio_io->data_dir &= ~SWD_IO;
+ break;
+ case 'o':
+ gpio_io->data_dir |= SWD_IO;
+ break;
+ case 'R':
+ in = '0' + !!(gpio_io->in & SWD_IO);
+ serial_write(0, &in, 1);
+ gpio_green->out ^= LED_GREEN;
+ break;
+ default:
+ gpio_red->out ^= LED_RED;
+ }
+}
+
+/***************************************************************************** */
+int main(void) {
+ system_init();
+ config_gpio(&swd_io, LPC_IO_MODE_PULL_UP, GPIO_DIR_OUT, 1);
+ config_gpio(&swd_clk, LPC_IO_MODE_PULL_UP, GPIO_DIR_OUT, 1);
+ uart_on(0, 115200, uart_cb);
+ status_led(red_on);
+ while(1);
+ return 0;
+}