Frequency: Implementing for jlink.
SWD frequency is fixed for jlink according to the docs from 2010.
This commit is contained in:
parent
fdc654cfb3
commit
6dbb5ff7ee
|
@ -40,14 +40,19 @@
|
||||||
#define USB_VID_SEGGER_0105 0x0105
|
#define USB_VID_SEGGER_0105 0x0105
|
||||||
#define USB_VID_SEGGER_1020 0x1020
|
#define USB_VID_SEGGER_1020 0x1020
|
||||||
|
|
||||||
|
static uint32_t emu_caps;
|
||||||
|
static uint32_t emu_speed_kHz;
|
||||||
|
static uint16_t emu_min_divisor;
|
||||||
|
static uint16_t emu_current_divisor;
|
||||||
|
|
||||||
static void jlink_print_caps(bmp_info_t *info)
|
static void jlink_print_caps(bmp_info_t *info)
|
||||||
{
|
{
|
||||||
uint8_t cmd[1] = {CMD_GET_CAPS};
|
uint8_t cmd[1] = {CMD_GET_CAPS};
|
||||||
uint8_t res[4];
|
uint8_t res[4];
|
||||||
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
|
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
|
||||||
uint32_t caps = res[0] | (res[1] << 8) | (res[2] << 16) | (res[3] << 24);
|
emu_caps = res[0] | (res[1] << 8) | (res[2] << 16) | (res[3] << 24);
|
||||||
DEBUG_INFO("Caps %" PRIx32 "\n", caps);
|
DEBUG_INFO("Caps %" PRIx32 "\n", emu_caps);
|
||||||
if (caps & JLINK_CAP_GET_HW_VERSION) {
|
if (emu_caps & JLINK_CAP_GET_HW_VERSION) {
|
||||||
uint8_t cmd[1] = {CMD_GET_HW_VERSION};
|
uint8_t cmd[1] = {CMD_GET_HW_VERSION};
|
||||||
send_recv(info->usb_link, cmd, 1, NULL, 0);
|
send_recv(info->usb_link, cmd, 1, NULL, 0);
|
||||||
send_recv(info->usb_link, NULL, 0, res, sizeof(res));
|
send_recv(info->usb_link, NULL, 0, res, sizeof(res));
|
||||||
|
@ -57,13 +62,15 @@ static void jlink_print_caps(bmp_info_t *info)
|
||||||
}
|
}
|
||||||
static void jlink_print_speed(bmp_info_t *info)
|
static void jlink_print_speed(bmp_info_t *info)
|
||||||
{
|
{
|
||||||
uint8_t cmd[1] = {CMD_GET_SPEED};
|
uint8_t cmd[1] = {CMD_GET_SPEEDS};
|
||||||
uint8_t res[6];
|
uint8_t res[6];
|
||||||
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
|
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
|
||||||
uint32_t speed = res[0] | (res[1] << 8) | (res[2] << 16) | (res[3] << 24);
|
emu_speed_kHz = (res[0] | (res[1] << 8) | (res[2] << 16) | (res[3] << 24)) /
|
||||||
double freq_mhz = speed / 1000000.0;
|
1000;
|
||||||
uint16_t divisor = res[4] | (res[5] << 8);
|
emu_min_divisor = res[4] | (res[5] << 8);
|
||||||
DEBUG_INFO("Emulator speed %3.1f MHz, Mindiv %d\n", freq_mhz, divisor);
|
DEBUG_INFO("Emulator speed %d kHz, Mindiv %d%s\n", emu_speed_kHz,
|
||||||
|
emu_min_divisor,
|
||||||
|
(emu_caps & JLINK_CAP_GET_SPEEDS) ? "" : ", fixed");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jlink_print_version(bmp_info_t *info)
|
static void jlink_print_version(bmp_info_t *info)
|
||||||
|
@ -98,8 +105,8 @@ static void jlink_print_interfaces(bmp_info_t *info)
|
||||||
static void jlink_info(bmp_info_t *info)
|
static void jlink_info(bmp_info_t *info)
|
||||||
{
|
{
|
||||||
jlink_print_version(info);
|
jlink_print_version(info);
|
||||||
jlink_print_speed(info);
|
|
||||||
jlink_print_caps(info);
|
jlink_print_caps(info);
|
||||||
|
jlink_print_speed(info);
|
||||||
jlink_print_interfaces(info);
|
jlink_print_interfaces(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +221,7 @@ int jlink_init(bmp_info_t *info)
|
||||||
const char *jlink_target_voltage(bmp_info_t *info)
|
const char *jlink_target_voltage(bmp_info_t *info)
|
||||||
{
|
{
|
||||||
uint8_t cmd[1] = {CMD_GET_HW_STATUS};
|
uint8_t cmd[1] = {CMD_GET_HW_STATUS};
|
||||||
uint8_t res[8];
|
uint8_t res[8];
|
||||||
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
|
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
|
||||||
uint16_t mVolt = res[0] | (res[1] << 8);
|
uint16_t mVolt = res[0] | (res[1] << 8);
|
||||||
static char ret[7];
|
static char ret[7];
|
||||||
|
@ -238,3 +245,27 @@ bool jlink_srst_get_val(bmp_info_t *info) {
|
||||||
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
|
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
|
||||||
return !(res[6]);
|
return !(res[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jlink_max_frequency_set(bmp_info_t *info, uint32_t freq)
|
||||||
|
{
|
||||||
|
if (!(emu_caps & JLINK_CAP_GET_SPEEDS))
|
||||||
|
return;
|
||||||
|
if (!info->is_jtag)
|
||||||
|
return;
|
||||||
|
uint16_t freq_kHz = freq /1000;
|
||||||
|
uint16_t divisor = (emu_speed_kHz + freq_kHz - 1) / freq_kHz;
|
||||||
|
if (divisor < emu_min_divisor)
|
||||||
|
divisor = emu_min_divisor;
|
||||||
|
emu_current_divisor = divisor;
|
||||||
|
uint16_t speed_kHz = emu_speed_kHz / divisor;
|
||||||
|
uint8_t cmd[3] = {CMD_SET_SPEED, speed_kHz & 0xff, speed_kHz >> 8};
|
||||||
|
DEBUG_WARN("Set Speed %d\n", speed_kHz);
|
||||||
|
send_recv(info->usb_link, cmd, 3, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t jlink_max_frequency_get(bmp_info_t *info)
|
||||||
|
{
|
||||||
|
if ((emu_caps & JLINK_CAP_GET_SPEEDS) && (info->is_jtag))
|
||||||
|
return (emu_speed_kHz * 1000L)/ emu_current_divisor;
|
||||||
|
return FREQ_FIXED;
|
||||||
|
}
|
||||||
|
|
|
@ -24,8 +24,9 @@
|
||||||
|
|
||||||
/** @cond PRIVATE */
|
/** @cond PRIVATE */
|
||||||
#define CMD_GET_VERSION 0x01
|
#define CMD_GET_VERSION 0x01
|
||||||
|
#define CMD_SET_SPEED 0x05
|
||||||
#define CMD_GET_HW_STATUS 0x07
|
#define CMD_GET_HW_STATUS 0x07
|
||||||
#define CMD_GET_SPEED 0xc0
|
#define CMD_GET_SPEEDS 0xc0
|
||||||
#define CMD_GET_SELECT_IF 0xc7
|
#define CMD_GET_SELECT_IF 0xc7
|
||||||
#define CMD_HW_JTAG3 0xcf
|
#define CMD_HW_JTAG3 0xcf
|
||||||
#define CMD_HW_RESET0 0xdc
|
#define CMD_HW_RESET0 0xdc
|
||||||
|
@ -37,7 +38,8 @@
|
||||||
#define JLINK_IF_GET_ACTIVE 0xfe
|
#define JLINK_IF_GET_ACTIVE 0xfe
|
||||||
#define JLINK_IF_GET_AVAILABLE 0xff
|
#define JLINK_IF_GET_AVAILABLE 0xff
|
||||||
|
|
||||||
#define JLINK_CAP_GET_HW_VERSION 2
|
#define JLINK_CAP_GET_SPEEDS (1 << 9)
|
||||||
|
#define JLINK_CAP_GET_HW_VERSION (1 << 1)
|
||||||
#define JLINK_IF_JTAG 1
|
#define JLINK_IF_JTAG 1
|
||||||
#define JLINK_IF_SWD 2
|
#define JLINK_IF_SWD 2
|
||||||
|
|
||||||
|
@ -53,13 +55,54 @@ int jlink_jtagtap_init(bmp_info_t *info, jtag_proc_t *jtag_proc) {return 0;};
|
||||||
const char *jlink_target_voltage(bmp_info_t *info) {return "ERROR";};
|
const char *jlink_target_voltage(bmp_info_t *info) {return "ERROR";};
|
||||||
void jlink_srst_set_val(bmp_info_t *info, bool assert) {};
|
void jlink_srst_set_val(bmp_info_t *info, bool assert) {};
|
||||||
bool jlink_srst_get_val(bmp_info_t *info) {return true;};
|
bool jlink_srst_get_val(bmp_info_t *info) {return true;};
|
||||||
|
void jlink_max_frequency_set(bmp_info_t *info, uint32_t freq) {};
|
||||||
|
uint32_t jlink_max_frequency_get(bmp_info_t *info) {return 0;};
|
||||||
# pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
#else
|
#else
|
||||||
|
/** Device capabilities. (from openocd*/
|
||||||
|
enum jaylink_device_capability {
|
||||||
|
/** Device supports retrieval of the hardware version. */
|
||||||
|
JAYLINK_DEV_CAP_GET_HW_VERSION = 1,
|
||||||
|
/** Device supports adaptive clocking. */
|
||||||
|
JAYLINK_DEV_CAP_ADAPTIVE_CLOCKING = 3,
|
||||||
|
/** Device supports reading configuration data. */
|
||||||
|
JAYLINK_DEV_CAP_READ_CONFIG = 4,
|
||||||
|
/** Device supports writing configuration data. */
|
||||||
|
JAYLINK_DEV_CAP_WRITE_CONFIG = 5,
|
||||||
|
/** Device supports retrieval of target interface speeds. */
|
||||||
|
JAYLINK_DEV_CAP_GET_SPEEDS = 9,
|
||||||
|
/** Device supports retrieval of free memory size. */
|
||||||
|
JAYLINK_DEV_CAP_GET_FREE_MEMORY = 11,
|
||||||
|
/** Device supports retrieval of hardware information. */
|
||||||
|
JAYLINK_DEV_CAP_GET_HW_INFO = 12,
|
||||||
|
/** Device supports the setting of the target power supply. */
|
||||||
|
JAYLINK_DEV_CAP_SET_TARGET_POWER = 13,
|
||||||
|
/** Device supports target interface selection. */
|
||||||
|
JAYLINK_DEV_CAP_SELECT_TIF = 17,
|
||||||
|
/** Device supports retrieval of counter values. */
|
||||||
|
JAYLINK_DEV_CAP_GET_COUNTERS = 19,
|
||||||
|
/** Device supports capturing of SWO trace data. */
|
||||||
|
JAYLINK_DEV_CAP_SWO = 23,
|
||||||
|
/** Device supports file I/O operations. */
|
||||||
|
JAYLINK_DEV_CAP_FILE_IO = 26,
|
||||||
|
/** Device supports registration of connections. */
|
||||||
|
JAYLINK_DEV_CAP_REGISTER = 27,
|
||||||
|
/** Device supports retrieval of extended capabilities. */
|
||||||
|
JAYLINK_DEV_CAP_GET_EXT_CAPS = 31,
|
||||||
|
/** Device supports EMUCOM. */
|
||||||
|
JAYLINK_DEV_CAP_EMUCOM = 33,
|
||||||
|
/** Device supports ethernet connectivity. */
|
||||||
|
JAYLINK_DEV_CAP_ETHERNET = 38
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int jlink_init(bmp_info_t *info);
|
int jlink_init(bmp_info_t *info);
|
||||||
int jlink_swdp_scan(bmp_info_t *info);
|
int jlink_swdp_scan(bmp_info_t *info);
|
||||||
int jlink_jtagtap_init(bmp_info_t *info, jtag_proc_t *jtag_proc);
|
int jlink_jtagtap_init(bmp_info_t *info, jtag_proc_t *jtag_proc);
|
||||||
const char *jlink_target_voltage(bmp_info_t *info);
|
const char *jlink_target_voltage(bmp_info_t *info);
|
||||||
void jlink_srst_set_val(bmp_info_t *info, bool assert);
|
void jlink_srst_set_val(bmp_info_t *info, bool assert);
|
||||||
bool jlink_srst_get_val(bmp_info_t *info);
|
bool jlink_srst_get_val(bmp_info_t *info);
|
||||||
|
void jlink_max_frequency_set(bmp_info_t *info, uint32_t freq);
|
||||||
|
uint32_t jlink_max_frequency_get(bmp_info_t *info);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -339,10 +339,21 @@ void platform_max_frequency_set(uint32_t freq)
|
||||||
case BMP_TYPE_STLINKV2:
|
case BMP_TYPE_STLINKV2:
|
||||||
stlink_max_frequency_set(&info, freq);
|
stlink_max_frequency_set(&info, freq);
|
||||||
break;
|
break;
|
||||||
|
case BMP_TYPE_JLINK:
|
||||||
|
jlink_max_frequency_set(&info, freq);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DEBUG_WARN("Setting max SWJ frequency not yet implemented\n");
|
DEBUG_WARN("Setting max SWJ frequency not yet implemented\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
uint32_t max_freq = platform_max_frequency_get();
|
||||||
|
if (max_freq == FREQ_FIXED)
|
||||||
|
DEBUG_INFO("Device has fixed frequency for %s\n",
|
||||||
|
(info.is_jtag) ? "JTAG" : "SWD" );
|
||||||
|
else
|
||||||
|
DEBUG_INFO("Speed set to %7.4f MHz for %s\n",
|
||||||
|
platform_max_frequency_get() / 1000000.0,
|
||||||
|
(info.is_jtag) ? "JTAG" : "SWD" );
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t platform_max_frequency_get(void)
|
uint32_t platform_max_frequency_get(void)
|
||||||
|
@ -357,6 +368,8 @@ uint32_t platform_max_frequency_get(void)
|
||||||
return libftdi_max_frequency_get();
|
return libftdi_max_frequency_get();
|
||||||
case BMP_TYPE_STLINKV2:
|
case BMP_TYPE_STLINKV2:
|
||||||
return stlink_max_frequency_get(&info);
|
return stlink_max_frequency_get(&info);
|
||||||
|
case BMP_TYPE_JLINK:
|
||||||
|
return jlink_max_frequency_get(&info);
|
||||||
default:
|
default:
|
||||||
DEBUG_WARN("Reading max SWJ frequency not yet implemented\n");
|
DEBUG_WARN("Reading max SWJ frequency not yet implemented\n");
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue