Change jtag_rclk behaviour so it can be called before the interface init function

git-svn-id: svn://svn.berlios.de/openocd/trunk@2590 b42882b7-edfa-0310-969c-e2dbd0fdcd60
__archive__
ntfreak 2009-08-18 12:14:01 +00:00
parent 7b4428df97
commit bb5086b83e
4 changed files with 133 additions and 41 deletions

View File

@ -134,15 +134,6 @@ proc ocd_gdb_restart {target_num} {
reset halt
}
# If RCLK is not supported, use fallback_speed_khz
proc jtag_rclk {fallback_speed_khz} {
if {[catch {jtag_khz 0}]!=0} {
jtag_khz $fallback_speed_khz
}
}
add_help_text jtag_rclk "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed"
proc ocd_process_reset { MODE } {
# If this target must be halted...

View File

@ -101,8 +101,9 @@ static jtag_event_callback_t *jtag_event_callbacks;
/* speed in kHz*/
static int speed_khz = 0;
/* flag if the kHz speed was defined */
static bool hasKHz = false;
/* speed to fallback to when RCLK is requested but not supported */
static int rclk_fallback_speed_khz = 0;
static enum {CLOCK_MODE_SPEED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode;
static int jtag_speed = 0;
static struct jtag_interface_s *jtag = NULL;
@ -1140,16 +1141,34 @@ int jtag_interface_init(struct command_context_s *cmd_ctx)
LOG_ERROR("JTAG interface has to be specified, see \"interface\" command");
return ERROR_JTAG_INVALID_INTERFACE;
}
if (hasKHz)
{
jtag_interface->khz(jtag_get_speed_khz(), &jtag_speed);
hasKHz = false;
}
if (jtag_interface->init() != ERROR_OK)
return ERROR_JTAG_INIT_FAILED;
jtag = jtag_interface;
if (jtag_interface->init() != ERROR_OK)
{
jtag = NULL;
return ERROR_JTAG_INIT_FAILED;
}
int requested_khz = jtag_get_speed_khz();
int actual_khz = requested_khz;
int retval = jtag_get_speed_readable(&actual_khz);
if (ERROR_OK != retval)
return retval;
if (actual_khz)
{
if ((CLOCK_MODE_RCLK == clock_mode)
|| ((CLOCK_MODE_KHZ == clock_mode) && !requested_khz))
{
LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz"
, actual_khz);
}
else
LOG_INFO("clock speed %d kHz", actual_khz);
}
else
LOG_INFO("RCLK (adaptive clock speed)");
return ERROR_OK;
}
@ -1255,20 +1274,15 @@ int jtag_init(struct command_context_s *cmd_ctx)
return jtag_init_reset(cmd_ctx);
}
void jtag_set_speed_khz(unsigned khz)
{
speed_khz = khz;
}
unsigned jtag_get_speed_khz(void)
{
return speed_khz;
}
int jtag_config_khz(unsigned khz)
{
LOG_DEBUG("handle jtag khz");
jtag_set_speed_khz(khz);
int cur_speed = 0;
static int jtag_khz_to_speed(unsigned khz, int* speed)
{
LOG_DEBUG("convert khz to interface specific speed value");
speed_khz = khz;
if (jtag != NULL)
{
LOG_DEBUG("have interface set up");
@ -1276,33 +1290,84 @@ int jtag_config_khz(unsigned khz)
int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
if (ERROR_OK != retval)
{
jtag_set_speed_khz(0);
return retval;
}
cur_speed = speed_div1;
*speed = speed_div1;
}
return jtag_set_speed(cur_speed);
return ERROR_OK;
}
int jtag_get_speed(void)
static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int* speed)
{
return jtag_speed;
int retval = jtag_khz_to_speed(0, speed);
if ((ERROR_OK != retval) && fallback_speed_khz)
{
LOG_DEBUG("trying fallback speed...");
retval = jtag_khz_to_speed(fallback_speed_khz, speed);
}
return retval;
}
int jtag_set_speed(int speed)
static int jtag_set_speed(int speed)
{
jtag_speed = speed;
/* this command can be called during CONFIG,
* in which case jtag isn't initialized */
hasKHz = !jtag;
return jtag ? jtag->speed(speed) : ERROR_OK;
}
int jtag_get_speed_readable(int *speed)
int jtag_config_speed(int speed)
{
return jtag ? jtag->speed_div(jtag_get_speed(), speed) : ERROR_OK;
LOG_DEBUG("handle jtag speed");
clock_mode = CLOCK_MODE_SPEED;
return jtag_set_speed(speed);
}
int jtag_config_khz(unsigned khz)
{
LOG_DEBUG("handle jtag khz");
clock_mode = CLOCK_MODE_KHZ;
int speed = 0;
int retval = jtag_khz_to_speed(khz, &speed);
return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
}
int jtag_config_rclk(unsigned fallback_speed_khz)
{
LOG_DEBUG("handle jtag rclk");
clock_mode = CLOCK_MODE_RCLK;
rclk_fallback_speed_khz = fallback_speed_khz;
int speed = 0;
int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed);
return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
}
int jtag_get_speed(void)
{
int speed;
switch(clock_mode)
{
case CLOCK_MODE_SPEED:
speed = jtag_speed;
break;
case CLOCK_MODE_KHZ:
jtag_khz_to_speed(jtag_get_speed_khz(), &speed);
break;
case CLOCK_MODE_RCLK:
jtag_rclk_to_speed(rclk_fallback_speed_khz, &speed);
break;
default:
LOG_ERROR("BUG: unknown jtag clock mode");
speed = 0;
break;
}
return speed;
}
int jtag_get_speed_readable(int *khz)
{
return jtag ? jtag->speed_div(jtag_get_speed(), khz) : ERROR_OK;
}
void jtag_set_verify(bool enable)
{

View File

@ -252,13 +252,16 @@ int jtag_get_speed_readable(int *speed);
* @returns ERROR_OK during configuration or on success, or an error
* code returned from the interface @c speed callback.
*/
int jtag_set_speed(int speed);
int jtag_config_speed(int speed);
/// Attempt to configure the interface for the specified KHz.
int jtag_config_khz(unsigned khz);
/// Set the clock speed of the JTAG interface in KHz.
void jtag_set_speed_khz(unsigned speed);
/**
* Attempt to enable RTCK/RCLK. If that fails, fallback to the
* specified frequency.
*/
int jtag_config_rclk(unsigned fallback_speed_khz);
/// Retreives the clock speed of the JTAG interface in KHz.
unsigned jtag_get_speed_khz(void);

View File

@ -55,6 +55,7 @@ static int handle_interface_list_command(struct command_context_s *cmd_ctx,
static int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_rclk_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
@ -577,6 +578,8 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command,
COMMAND_ANY, "set maximum jtag speed (if supported); "
"parameter is maximum khz, or 0 for adaptive clocking (RTCK).");
register_command(cmd_ctx, NULL, "jtag_rclk", handle_jtag_rclk_command,
COMMAND_ANY, "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed");
register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command,
COMMAND_CONFIG, "(DEPRECATED) jtag_device <ir_length> <ir_expected> <ir_mask>");
register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
@ -955,7 +958,7 @@ static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cm
int retval = parse_uint(args[0], &cur_speed);
if (ERROR_OK != retval)
return retval;
retval = jtag_set_speed(cur_speed);
retval = jtag_config_speed(cur_speed);
}
command_print(cmd_ctx, "jtag_speed: %d", jtag_get_speed());
@ -993,6 +996,36 @@ static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd,
return retval;
}
static int handle_jtag_rclk_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
if (argc > 1)
return ERROR_COMMAND_SYNTAX_ERROR;
int retval = ERROR_OK;
if (argc == 1)
{
unsigned khz = 0;
int retval = parse_uint(args[0], &khz);
if (ERROR_OK != retval)
return retval;
retval = jtag_config_rclk(khz);
if (ERROR_OK != retval)
return retval;
}
int cur_khz = jtag_get_speed_khz();
retval = jtag_get_speed_readable(&cur_khz);
if (ERROR_OK != retval)
return retval;
if (cur_khz)
command_print(cmd_ctx, "RCLK not supported - fallback to %d kHz", cur_khz);
else
command_print(cmd_ctx, "RCLK - adaptive");
return retval;
}
static int handle_jtag_reset_command(struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc)
{