static void stlink_usb_init_buffer(void *handle, uint8_t direction, uint32_t size);
static int stlink_swim_status(void *handle);
+void stlink_dump_speed_map(const struct speed_map *map, unsigned int map_size);
+static int stlink_get_com_freq(void *handle, bool is_jtag, struct speed_map *map);
+static int stlink_speed(void *handle, int khz, bool query);
/** */
static unsigned int stlink_usb_block(void *handle)
}
/** */
-static int stlink_usb_init_mode(void *handle, bool connect_under_reset)
+static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int initial_interface_speed)
{
int res;
uint8_t mode;
return ERROR_FAIL;
}
+ /* set the speed before entering the mode, as the chip discovery phase should be done at this speed too */
+ if (h->transport == HL_TRANSPORT_JTAG) {
+ if (h->version.flags & STLINK_F_HAS_JTAG_SET_FREQ) {
+ stlink_dump_speed_map(stlink_khz_to_speed_map_jtag, ARRAY_SIZE(stlink_khz_to_speed_map_jtag));
+ stlink_speed(h, initial_interface_speed, false);
+ }
+ } else if (h->transport == HL_TRANSPORT_SWD) {
+ if (h->version.flags & STLINK_F_HAS_SWD_SET_FREQ) {
+ stlink_dump_speed_map(stlink_khz_to_speed_map_swd, ARRAY_SIZE(stlink_khz_to_speed_map_swd));
+ stlink_speed(h, initial_interface_speed, false);
+ }
+ }
+
+ if (h->version.jtag_api == STLINK_JTAG_API_V3) {
+ struct speed_map map[STLINK_V3_MAX_FREQ_NB];
+
+ stlink_get_com_freq(h, (h->transport == HL_TRANSPORT_JTAG), map);
+ stlink_dump_speed_map(map, ARRAY_SIZE(map));
+ stlink_speed(h, initial_interface_speed, false);
+ }
+
/* preliminary SRST assert:
* We want SRST is asserted before activating debug signals (mode_enter).
* As the required mode has not been set, the adapter may not know what pin to use.
}
/* initialize the debug hardware */
- err = stlink_usb_init_mode(h, param->connect_under_reset);
+ err = stlink_usb_init_mode(h, param->connect_under_reset, param->initial_interface_speed);
if (err != ERROR_OK) {
LOG_ERROR("init mode failed (unable to connect to the target)");
return ERROR_OK;
}
- if (h->transport == HL_TRANSPORT_JTAG) {
- if (h->version.flags & STLINK_F_HAS_JTAG_SET_FREQ) {
- stlink_dump_speed_map(stlink_khz_to_speed_map_jtag, ARRAY_SIZE(stlink_khz_to_speed_map_jtag));
- stlink_speed(h, param->initial_interface_speed, false);
- }
- } else if (h->transport == HL_TRANSPORT_SWD) {
- if (h->version.flags & STLINK_F_HAS_SWD_SET_FREQ) {
- stlink_dump_speed_map(stlink_khz_to_speed_map_swd, ARRAY_SIZE(stlink_khz_to_speed_map_swd));
- stlink_speed(h, param->initial_interface_speed, false);
- }
- }
-
- if (h->version.jtag_api == STLINK_JTAG_API_V3) {
- struct speed_map map[STLINK_V3_MAX_FREQ_NB];
-
- stlink_get_com_freq(h, (h->transport == HL_TRANSPORT_JTAG), map);
- stlink_dump_speed_map(map, ARRAY_SIZE(map));
- stlink_speed(h, param->initial_interface_speed, false);
- }
-
/* get cpuid, so we can determine the max page size
* start with a safe default */
h->max_mem_packet = (1 << 10);
return ERROR_FAIL;
}
-int stlink_config_trace(void *handle, bool enabled, enum tpiu_pin_protocol pin_protocol,
- uint32_t port_size, unsigned int *trace_freq)
+int stlink_config_trace(void *handle, bool enabled,
+ enum tpiu_pin_protocol pin_protocol, uint32_t port_size,
+ unsigned int *trace_freq, unsigned int traceclkin_freq,
+ uint16_t *prescaler)
{
struct stlink_usb_handle_s *h = handle;
+ uint16_t presc;
if (enabled && (!(h->version.flags & STLINK_F_HAS_TRACE) ||
pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART)) {
if (!*trace_freq)
*trace_freq = STLINK_TRACE_MAX_HZ;
+
+ presc = traceclkin_freq / *trace_freq;
+
+ if (traceclkin_freq % *trace_freq > 0)
+ presc++;
+
+ if (presc > TPIU_ACPR_MAX_SWOSCALER) {
+ LOG_ERROR("SWO frequency is not suitable. Please choose a different "
+ "frequency.");
+ return ERROR_FAIL;
+ }
+
+ *prescaler = presc;
h->trace.source_hz = *trace_freq;
return stlink_usb_trace_enable(h);