jtaglib: implement single-stepping.

This commit is contained in:
Peter Bägel (DF5EQ) 2015-02-24 11:16:46 +13:00 committed by Daniel Beer
parent 50684f5991
commit 320e560b99
3 changed files with 68 additions and 25 deletions

View File

@ -1,6 +1,6 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009-2012 Daniel Beer
* Copyright (C) 2012 Peter Bägel
* Copyright (C) 2012-2014 Peter Bägel
*
* 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
@ -20,6 +20,10 @@
/* jtag functions are taken from TIs SLAA149September 2002
*
* 2012-10-03 Peter Bägel (DF5EQ)
* 2012-10-03 initial release Peter Bägel (DF5EQ)
* 2014-12-26 jtag_single_step added Peter Bägel (DF5EQ)
* jtag_read_reg corrected
* jtag_write_reg corrected
*/
#include <stdlib.h>
@ -419,9 +423,11 @@ unsigned int jtag_get_device(struct jtdev *p)
* timeout after a limited number of attempts
*/
jtag_id = jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
for (loop_counter = 50;
loop_counter > 0 && ((jtag_dr_shift(p, 0x0000) & 0x0200) != 0x0200);
loop_counter--);
for ( loop_counter = 50; loop_counter > 0; loop_counter--) {
if ( (jtag_dr_shift(p, 0x0000) & 0x0200) == 0x0200 ) {
break;
}
}
if (loop_counter == 0) {
printc_err("jtag_get_device: timed out\n");
@ -896,15 +902,11 @@ address_t jtag_read_reg(struct jtdev *p, int reg)
jtag_set_instruction_fetch(p);
jtag_ir_shift(p, IR_DATA_16BIT);
/* "sub #8,PC" instruction
* PC - 8 -> PC
* PC is advanced 4 bytes by this instruction
* needs 3 clock cycles
*/
jtag_dr_shift(p, 0x8030);
jtag_tclk_set(p);
jtag_tclk_clr(p);
jtag_dr_shift(p, 0x0008);
/* "jmp $-4" instruction */
/* PC - 4 -> PC */
/* needs 2 clock cycles */
jtag_dr_shift(p, 0x3ffd);
jtag_tclk_set(p);
jtag_tclk_clr(p);
jtag_tclk_set(p);
@ -936,6 +938,8 @@ address_t jtag_read_reg(struct jtdev *p, int reg)
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401);
jtag_tclk_set(p);
/* Return value read from register */
return value;
}
@ -951,15 +955,11 @@ void jtag_write_reg(struct jtdev *p, int reg, address_t value)
jtag_set_instruction_fetch(p);
jtag_ir_shift(p, IR_DATA_16BIT);
/* "sub #8,PC" instruction
* PC-8 -> PC
* PC is advanced 4 bytes by this instruction
* needs 3 clock cycles
*/
jtag_dr_shift(p, 0x8030);
jtag_tclk_set(p);
jtag_tclk_clr(p);
jtag_dr_shift(p, 0x0008);
/* "jmp $-4" instruction */
/* PC - 4 -> PC */
/* needs 4 clock cycles */
jtag_dr_shift(p, 0x3ffd);
jtag_tclk_set(p);
jtag_tclk_clr(p);
jtag_tclk_set(p);
@ -973,11 +973,45 @@ void jtag_write_reg(struct jtdev *p, int reg, address_t value)
jtag_dr_shift(p, 0x4030 | (reg & 0x000f) );
jtag_tclk_set(p);
jtag_tclk_clr(p);
jtag_dr_shift(p, reg==0 ? value-4 : value );
jtag_dr_shift(p, value);
jtag_tclk_set(p);
jtag_tclk_clr(p);
/* JTAG controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401);
jtag_tclk_set(p);
}
/*----------------------------------------------------------------------------*/
void jtag_single_step( struct jtdev *p )
{
unsigned int loop_counter;
/* CPU controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x3401);
/* clock CPU until next instruction fetch cycle */
/* failure after 10 clock cycles */
/* this is more than for the longest instruction */
jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
for (loop_counter = 10; loop_counter > 0; loop_counter--) {
jtag_tclk_clr(p);
jtag_tclk_set(p);
if ((jtag_dr_shift(p, 0x0000) & 0x0080) == 0x0080) {
break;
}
}
/* JTAG controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401);
if (loop_counter == 0) {
/* timeout reached */
printc_err("pif: single step failed\n");
p->failed = 1;
}
}

View File

@ -1,6 +1,6 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009-2012 Daniel Beer
* Copyright (C) 2012 Peter Bägel
* Copyright (C) 2012-2014 Peter Bägel
*
* 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
@ -20,6 +20,8 @@
/* jtag functions are taken from TIs SLAA149September 2002
*
* 2012-10-03 Peter Bägel (DF5EQ)
* 2012-10-03 initial release Peter Bägel (DF5EQ)
* 2014-12-26 jtag_single_step added Peter Bägel (DF5EQ)
*/
#ifndef JTAGLIB_H_
@ -102,5 +104,6 @@ address_t jtag_read_reg(struct jtdev *p, int reg);
/* Writes a value into a register of the target CPU */
void jtag_write_reg(struct jtdev *p, int reg, address_t value);
void jtag_single_step(struct jtdev *p);
#endif

View File

@ -1,6 +1,6 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009-2012 Daniel Beer
* Copyright (C) 2012 Peter Bägel
* Copyright (C) 2012-2014 Peter Bägel
*
* 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
@ -21,6 +21,7 @@
* Starting point was the goodfet driver
*
* 2012-10-03 Peter Bägel (DF5EQ)
* 2014-12-26 single step implemented Peter Bägel (DF5EQ)
*/
#include <stdlib.h>
@ -286,6 +287,11 @@ static int pif_ctl(device_t dev_base, device_ctl_t type)
jtag_get_device(&dev->jtag);
break;
case DEVICE_CTL_STEP:
/* execute next instruction at current PC */
jtag_single_step(&dev->jtag);
break;
default:
printc_err("pif: unsupported operation\n");
return -1;