--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com
+ *
+ * SWIM (Single Wire Interface Module) is a low-pin-count debug protocol
+ * used by STMicroelectronics MCU family STM8 and documented in UM470
+ * https://www.st.com/resource/en/user_manual/cd00173911.pdf
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "interface.h"
+#include "swim.h"
+#include "jtag/hla/hla_transport.h"
+#include "jtag/hla/hla_interface.h"
+#include "jtag/hla/hla_layout.h"
+
+extern struct adapter_driver *adapter_driver;
+
+int swim_system_reset(void)
+{
+ assert(adapter_driver->hla_if);
+
+ return adapter_driver->hla_if->layout->api->reset(adapter_driver->hla_if->handle);
+}
+
+int swim_read_mem(uint32_t addr, uint32_t size, uint32_t count,
+ uint8_t *buffer)
+{
+ assert(adapter_driver->hla_if);
+
+ return adapter_driver->hla_if->layout->api->read_mem(adapter_driver->hla_if->handle, addr, size, count, buffer);
+}
+
+int swim_write_mem(uint32_t addr, uint32_t size, uint32_t count,
+ const uint8_t *buffer)
+{
+ assert(adapter_driver->hla_if);
+
+ return adapter_driver->hla_if->layout->api->write_mem(adapter_driver->hla_if->handle, addr, size, count, buffer);
+}
+
+int swim_reconnect(void)
+{
+ assert(adapter_driver->hla_if);
+
+ return adapter_driver->hla_if->layout->api->state(adapter_driver->hla_if->handle);
+}
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com
+ */
+
+/**
+ * @file
+ * This file implements support for STMicroelectronics debug protocol SWIM
+ * (Single Wire Interface Module).
+ */
+
+#ifndef OPENOCD_JTAG_SWIM_H
+#define OPENOCD_JTAG_SWIM_H
+
+struct swim_driver {
+ /**
+ * Send SRST (system reset) command to target.
+ *
+ * @return ERROR_OK on success, else a fault code.
+ */
+ int (*srst)(void);
+
+ /**
+ * Read target memory through ROTF (read on-the-fly) command.
+ *
+ * @param addr Start address to read data from target memory.
+ * @param size Size in bytes of data units, 1, 2 or 4.
+ * @param count Number of units (size units, not bytes) to read.
+ * @param buffer Data buffer to receive data.
+ * @return ERROR_OK on success, else a fault code.
+ */
+ int (*read_mem)(uint32_t addr, uint32_t size, uint32_t count,
+ uint8_t *buffer);
+
+ /**
+ * Write target memory through WOTF (write on-the-fly) command.
+ *
+ * @param addr Start address to write data to target memory.
+ * @param size Size in bytes of data units, 1, 2 or 4.
+ * @param count Number of units (size units, not bytes) to write.
+ * @param buffer Data buffer to write.
+ * @return ERROR_OK on success, else a fault code.
+ */
+ int (*write_mem)(uint32_t addr, uint32_t size, uint32_t count,
+ const uint8_t *buffer);
+
+ /**
+ * Reconnect to the target.
+ * Should be reworked to be more generic and not linked to current
+ * implementation in stlink driver.
+ *
+ * @return ERROR_OK on success, else a fault code.
+ */
+ int (*reconnect)(void);
+};
+
+int swim_system_reset(void);
+int swim_read_mem(uint32_t addr, uint32_t size, uint32_t count,
+ uint8_t *buffer);
+int swim_write_mem(uint32_t addr, uint32_t size, uint32_t count,
+ const uint8_t *buffer);
+int swim_reconnect(void);
+
+#endif /* OPENOCD_JTAG_SWIM_H */
#include "hello.h"
#include "jtag/interface.h"
#include "jtag/jtag.h"
-#include "jtag/hla/hla_transport.h"
-#include "jtag/hla/hla_interface.h"
-#include "jtag/hla/hla_layout.h"
+#include "jtag/swim.h"
#include "register.h"
#include "breakpoints.h"
#include "algorithm.h"
enum hw_break_type type;
};
-static inline struct hl_interface_s *target_to_adapter(struct target *target)
-{
- return target->tap->priv;
-}
-
static int stm8_adapter_read_memory(struct target *target,
uint32_t addr, int size, int count, void *buf)
{
- int ret;
- struct hl_interface_s *adapter = target_to_adapter(target);
-
- ret = adapter->layout->api->read_mem(adapter->handle,
- addr, size, count, buf);
- if (ret != ERROR_OK)
- return ret;
- return ERROR_OK;
+ return swim_read_mem(addr, size, count, buf);
}
static int stm8_adapter_write_memory(struct target *target,
uint32_t addr, int size, int count, const void *buf)
{
- int ret;
- struct hl_interface_s *adapter = target_to_adapter(target);
-
- ret = adapter->layout->api->write_mem(adapter->handle,
- addr, size, count, buf);
- if (ret != ERROR_OK)
- return ret;
- return ERROR_OK;
+ return swim_write_mem(addr, size, count, buf);
}
static int stm8_write_u8(struct target *target,
uint32_t addr, uint8_t val)
{
- int ret;
uint8_t buf[1];
- struct hl_interface_s *adapter = target_to_adapter(target);
buf[0] = val;
- ret = adapter->layout->api->write_mem(adapter->handle, addr, 1, 1, buf);
- if (ret != ERROR_OK)
- return ret;
- return ERROR_OK;
+ return swim_write_mem(addr, 1, 1, buf);
}
static int stm8_read_u8(struct target *target,
uint32_t addr, uint8_t *val)
{
- int ret;
- struct hl_interface_s *adapter = target_to_adapter(target);
-
- ret = adapter->layout->api->read_mem(adapter->handle, addr, 1, 1, val);
- if (ret != ERROR_OK)
- return ret;
- return ERROR_OK;
-}
-
-static int stm8_set_speed(struct target *target, int speed)
-{
- struct hl_interface_s *adapter = target_to_adapter(target);
- adapter->layout->api->speed(adapter->handle, speed, 0);
- return ERROR_OK;
+ return swim_read_mem(addr, 1, 1, val);
}
/*
static int stm8_reset_assert(struct target *target)
{
int res = ERROR_OK;
- struct hl_interface_s *adapter = target_to_adapter(target);
struct stm8_common *stm8 = target_to_stm8(target);
bool use_srst_fallback = true;
if (use_srst_fallback) {
LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
- res = adapter->layout->api->reset(adapter->handle);
+ res = swim_system_reset();
if (res != ERROR_OK)
return res;
}
uint8_t csr1, csr2;
/* get pointers to arch-specific information */
struct stm8_common *stm8 = target_to_stm8(target);
- struct hl_interface_s *adapter = target_to_adapter(target);
+ enum reset_types jtag_reset_config = jtag_get_reset_config();
if (!target_was_examined(target)) {
if (!stm8->swim_configured) {
retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS);
if (retval != ERROR_OK)
return retval;
- retval = stm8_set_speed(target, 1);
- if (retval == ERROR_OK)
- stm8->swim_configured = true;
+ jtag_config_khz(1);
+ stm8->swim_configured = true;
/*
Now is the time to deassert reset if connect_under_reset.
Releasing reset line will cause the option bytes to load.
The core will still be stalled.
*/
- if (adapter->param.connect_under_reset)
- stm8_reset_deassert(target);
+ if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
+ if (jtag_reset_config & RESET_SRST_NO_GATING)
+ stm8_reset_deassert(target);
+ else
+ LOG_WARNING("\'srst_nogate\' reset_config option is required");
+ }
} else {
LOG_INFO("trying to reconnect");
- retval = adapter->layout->api->state(adapter->handle);
+ retval = swim_reconnect();
if (retval != ERROR_OK) {
LOG_ERROR("reconnect failed");
return ERROR_FAIL;