jtaglib: implement breakpoints.
This commit is contained in:
parent
320e560b99
commit
fdaad416b2
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* EEM_defs.h
|
||||||
|
*
|
||||||
|
* <FILEBRIEF>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||||
|
* its contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _EEM_DEFS_H_
|
||||||
|
#define _EEM_DEFS_H_
|
||||||
|
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
|
||||||
|
#define WRITE 0
|
||||||
|
#define READ 1
|
||||||
|
|
||||||
|
#define TRIGFLAG 0x8E
|
||||||
|
#define EEMVER 0x86
|
||||||
|
/* Definition for EEM General Clock Control Register */
|
||||||
|
#define GENCLKCTRL 0x88
|
||||||
|
/* Definitions for EEM General Clock Control Register */
|
||||||
|
#define MCLK_SEL0 0x0000
|
||||||
|
#define SMCLK_SEL0 0x0000
|
||||||
|
#define ACLK_SEL0 0x0000
|
||||||
|
#define MCLK_SEL3 0x6000
|
||||||
|
#define SMCLK_SEL3 0x0C00
|
||||||
|
#define ACLK_SEL3 0x0180
|
||||||
|
#define STOP_MCLK 0x0008
|
||||||
|
#define STOP_SMCLK 0x0004
|
||||||
|
#define STOP_ACLK 0x0002
|
||||||
|
/* Definition for EEM Module Clock Control Register 0 */
|
||||||
|
#define MODCLKCTRL0 0x8A
|
||||||
|
/* Definition for EEM General Debug Control Register */
|
||||||
|
#define GENCTRL 0x82
|
||||||
|
/* Definitions for EEM General Debug Control Register */
|
||||||
|
#define EEM_EN 0x0001
|
||||||
|
#define CLEAR_STOP 0x0002
|
||||||
|
#define EMU_CLK_EN 0x0004
|
||||||
|
#define EMU_FEAT_EN 0x0008
|
||||||
|
#define DEB_TRIG_LATCH 0x0010
|
||||||
|
#define EEM_RST 0x0040
|
||||||
|
#define E_STOPPED 0x0080
|
||||||
|
/* Defintions for Trigger Block base addresses */
|
||||||
|
#define TB0 0x0000
|
||||||
|
#define TB1 0x0008
|
||||||
|
#define TB2 0x0010
|
||||||
|
#define TB3 0x0018
|
||||||
|
#define TB4 0x0020
|
||||||
|
#define TB5 0x0028
|
||||||
|
#define TB6 0x0030
|
||||||
|
#define TB7 0x0038
|
||||||
|
#define TB8 0x0040
|
||||||
|
#define TB9 0x0048
|
||||||
|
/* Definitions for Trigger Block register addresses */
|
||||||
|
#define MBTRIGxVAL 0x0000
|
||||||
|
#define MBTRIGxCTL 0x0002
|
||||||
|
#define MBTRIGxMSK 0x0004
|
||||||
|
#define MBTRIGxCMB 0x0006
|
||||||
|
/* Definitions for MAB/MDB Trigger Control Register */
|
||||||
|
#define MAB 0x0000
|
||||||
|
#define MDB 0x0001
|
||||||
|
#define TRIG_0 0x0000 // Instruction Fetch
|
||||||
|
#define TRIG_1 0x0002 // Instruction Fetch Hold
|
||||||
|
#define TRIG_2 0x0004 // No Instruction Fetch
|
||||||
|
#define TRIG_3 0x0006 // Don't care
|
||||||
|
#define TRIG_4 0x0020 // No Instruction Fetch & Read
|
||||||
|
#define TRIG_5 0x0022 // No Instruction Fetch & Write
|
||||||
|
#define TRIG_6 0x0024 // Read
|
||||||
|
#define TRIG_7 0x0026 // Write
|
||||||
|
#define TRIG_8 0x0040 // No Instruction Fetch & No DMA Access
|
||||||
|
#define TRIG_9 0x0042 // DMA Access (Read or Write)
|
||||||
|
#define TRIG_A 0x0044 // No DMA Access
|
||||||
|
#define TRIG_B 0x0046 // Write & No DMA Access
|
||||||
|
#define TRIG_C 0x0060 // No Instruction Fetch & Read & No DMA Access
|
||||||
|
#define TRIG_D 0x0062 // Read & No DMA Access
|
||||||
|
#define TRIG_E 0x0064 // Read & DMA Access
|
||||||
|
#define TRIG_F 0x0066 // Write & DMA Access
|
||||||
|
#define CMP_EQUAL 0x0000
|
||||||
|
#define CMP_GREATER 0x0008
|
||||||
|
#define CMP_LESS 0x0010
|
||||||
|
#define CMP_NOT_EQUAL 0x0018
|
||||||
|
/* Definitions for MAB/MDB Trigger Mask Register */
|
||||||
|
#define NO_MASK 0x00000
|
||||||
|
#define MASK_ALL 0xFFFFF
|
||||||
|
#define MASK_XADDR 0xF0000
|
||||||
|
#define MASK_HBYTE 0x0FF00
|
||||||
|
#define MASK_LBYTE 0x000FF
|
||||||
|
/* Definitions for MAB/MDB Combination Register & Reaction Registers*/
|
||||||
|
#define EN0 0x0001
|
||||||
|
#define EN1 0x0002
|
||||||
|
#define EN2 0x0004
|
||||||
|
#define EN3 0x0008
|
||||||
|
#define EN4 0x0010
|
||||||
|
#define EN5 0x0020
|
||||||
|
#define EN6 0x0040
|
||||||
|
#define EN7 0x0080
|
||||||
|
#define EN8 0x0100
|
||||||
|
#define EN9 0x0200
|
||||||
|
|
||||||
|
#define STOR_CTL 0x9E
|
||||||
|
/* Definitions for State Storage Control Register */
|
||||||
|
#define VAR_WATCH0 0x0000 // Two
|
||||||
|
#define VAR_WATCH1 0x2000 // Four
|
||||||
|
#define VAR_WATCH2 0x4000 // Six
|
||||||
|
#define VAR_WATCH3 0x6000 // Eight
|
||||||
|
#define STOR_FULL 0x0200
|
||||||
|
#define STOR_WRIT 0x0100
|
||||||
|
#define STOR_TEST 0x0080
|
||||||
|
#define STOR_RST 0x0040
|
||||||
|
#define STOR_STOP_ON_TRIG 0x0020
|
||||||
|
#define STOR_START_ON_TRIG 0x0010
|
||||||
|
#define STOR_ONE_SHOT 0x0008
|
||||||
|
#define STOR_MODE0 0x0000 // Store on enabled triggers
|
||||||
|
#define STOR_MODE1 0x0002 // Store on Instruction Fetch
|
||||||
|
#define STOR_MODE2 0x0004 // Variable Watch
|
||||||
|
#define STOR_MODE3 0x0006 // Store all bus cycles
|
||||||
|
#define STOR_EN 0x0001 // enable state storage
|
||||||
|
|
||||||
|
/* Definitions for Reaction Registers */
|
||||||
|
#define STOR_REACT 0x98
|
||||||
|
#define BREAKREACT 0x80
|
||||||
|
#define EVENT_REACT 0x94
|
||||||
|
|
||||||
|
#define EVENT_CTRL 0x96
|
||||||
|
#define EVENT_TRIG 0x0001
|
||||||
|
|
||||||
|
/* Definitions for Cycle Counters */
|
||||||
|
#define CCNT0CTL 0xB0
|
||||||
|
#define CCNT0L 0xB2
|
||||||
|
#define CCNT0H 0xB4
|
||||||
|
#define CCNT1CTL 0xB8
|
||||||
|
#define CCNT1L 0xBA
|
||||||
|
#define CCNT1H 0xBC
|
||||||
|
#define CCNT1REACT 0xBE
|
||||||
|
|
||||||
|
/* Definitions for Cycle Counter Control Register */
|
||||||
|
#define CCNTMODE0 0x0000 // Counter stopped
|
||||||
|
#define CCNTMODE1 0x0001 // Increment on reaction
|
||||||
|
#define CCNTMODE4 0x0004 // Increment on instruction fetch cycles
|
||||||
|
#define CCNTMODE5 0x0005 // Increment on all bus cycles (including DMA cycles)
|
||||||
|
#define CCNTMODE6 0x0006 // Increment on all CPU bus cycles (excluding DMA cycles)
|
||||||
|
#define CCNTMODE7 0x0007 // Increment on all DMA bus cycles
|
||||||
|
#define CCNT_RST 0x0040
|
||||||
|
#define CCNTSTT0 0x0000 // Start when CPU released from JTAG/EEM
|
||||||
|
#define CCNTSTT1 0x0100 // Start on reaction CCNT1REACT (only CCNT1)
|
||||||
|
#define CCNTSTT2 0x0200 // Start when other (second) counter is started (only if available)
|
||||||
|
#define CCNTSTT3 0x0300 // Start immediately
|
||||||
|
#define CCNTSTP0 0x0000 // Stop when CPU is stopped by EEM or under JTAG control
|
||||||
|
#define CCNTSTP1 0x0400 // Stop on reaction CCNT1REACT (only CCNT1)
|
||||||
|
#define CCNTSTP2 0x0800 // Stop when other (second) counter is started (only if available)
|
||||||
|
#define CCNTSTP3 0x0C00 // No stop event
|
||||||
|
#define CCNTCLR0 0x0000 // No clear event
|
||||||
|
#define CCNTCLR1 0x1000 // Clear on reaction CCNT1REACT (only CCNT1)
|
||||||
|
#define CCNTCLR2 0x2000 // Clear when other (second) counter is started (only if available)
|
||||||
|
#define CCNTCLR3 0x3000 // Reserved
|
||||||
|
|
||||||
|
#define GCC_NONE 0x0000 // No clock control
|
||||||
|
#define GCC_STANDARD 0x0001 // Standard clock control
|
||||||
|
#define GCC_EXTENDED 0x0002 // Extended clock control
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,6 +1,6 @@
|
||||||
/* MSPDebug - debugging tool for MSP430 MCUs
|
/* MSPDebug - debugging tool for MSP430 MCUs
|
||||||
* Copyright (C) 2009-2012 Daniel Beer
|
* Copyright (C) 2009-2012 Daniel Beer
|
||||||
* Copyright (C) 2012-2014 Peter Bägel
|
* Copyright (C) 2012-2015 Peter Bägel
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,16 +19,23 @@
|
||||||
|
|
||||||
/* jtag functions are taken from TIs SLAA149–September 2002
|
/* jtag functions are taken from TIs SLAA149–September 2002
|
||||||
*
|
*
|
||||||
|
* breakpoint implementation influenced by a posting of Ruisheng Lin
|
||||||
|
* to Travis Goodspeed at 2012-09-20 found at:
|
||||||
|
* http://sourceforge.net/p/goodfet/mailman/message/29860790/
|
||||||
|
*
|
||||||
* 2012-10-03 Peter Bägel (DF5EQ)
|
* 2012-10-03 Peter Bägel (DF5EQ)
|
||||||
* 2012-10-03 initial release Peter Bägel (DF5EQ)
|
* 2012-10-03 initial release Peter Bägel (DF5EQ)
|
||||||
* 2014-12-26 jtag_single_step added Peter Bägel (DF5EQ)
|
* 2014-12-26 jtag_single_step added Peter Bägel (DF5EQ)
|
||||||
* jtag_read_reg corrected
|
* jtag_read_reg corrected
|
||||||
* jtag_write_reg corrected
|
* jtag_write_reg corrected
|
||||||
|
* 2015-02-21 jtag_set_breakpoint added Peter Bägel (DF5EQ)
|
||||||
|
* jtag_cpu_state added
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "jtaglib.h"
|
#include "jtaglib.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
#include "eem_defs.h"
|
||||||
|
|
||||||
/* JTAG identification value for all existing Flash-based MSP430 devices
|
/* JTAG identification value for all existing Flash-based MSP430 devices
|
||||||
*/
|
*/
|
||||||
|
@ -55,6 +62,10 @@
|
||||||
#define IR_EX_BLOW 0x24 /* 0x24 */
|
#define IR_EX_BLOW 0x24 /* 0x24 */
|
||||||
/* Bypass instruction */
|
/* Bypass instruction */
|
||||||
#define IR_BYPASS 0xFF /* 0xFF */
|
#define IR_BYPASS 0xFF /* 0xFF */
|
||||||
|
/* Instructions for the EEM */
|
||||||
|
#define IR_EMEX_DATA_EXCHANGE 0x90 /* 0x09 */
|
||||||
|
#define IR_EMEX_WRITE_CONTROL 0x30 /* 0x0C */
|
||||||
|
#define IR_EMEX_READ_CONTROL 0xD0 /* 0x0B */
|
||||||
|
|
||||||
#define jtag_tms_set(p) p->f->jtdev_tms(p, 1)
|
#define jtag_tms_set(p) p->f->jtdev_tms(p, 1)
|
||||||
#define jtag_tms_clr(p) p->f->jtdev_tms(p, 0)
|
#define jtag_tms_clr(p) p->f->jtdev_tms(p, 0)
|
||||||
|
@ -658,6 +669,9 @@ void jtag_release_device(struct jtdev *p, address_t address)
|
||||||
case 0xffff: /* Nothing to do */
|
case 0xffff: /* Nothing to do */
|
||||||
break;
|
break;
|
||||||
case 0xfffe: /* Perform reset */
|
case 0xfffe: /* Perform reset */
|
||||||
|
/* delete all breakpoints */
|
||||||
|
jtag_set_breakpoint(p,-1,0);
|
||||||
|
/* issue reset */
|
||||||
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
jtag_dr_shift(p, 0x2C01);
|
jtag_dr_shift(p, 0x2C01);
|
||||||
jtag_dr_shift(p, 0x2401);
|
jtag_dr_shift(p, 0x2401);
|
||||||
|
@ -667,6 +681,15 @@ void jtag_release_device(struct jtdev *p, address_t address)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jtag_set_instruction_fetch(p);
|
||||||
|
|
||||||
|
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE);
|
||||||
|
jtag_dr_shift(p, BREAKREACT + READ);
|
||||||
|
jtag_dr_shift(p, 0x0000);
|
||||||
|
|
||||||
|
jtag_ir_shift(p, IR_EMEX_WRITE_CONTROL);
|
||||||
|
jtag_dr_shift(p, 0x000f);
|
||||||
|
|
||||||
jtag_ir_shift(p, IR_CNTRL_SIG_RELEASE);
|
jtag_ir_shift(p, IR_CNTRL_SIG_RELEASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,3 +1038,78 @@ void jtag_single_step( struct jtdev *p )
|
||||||
p->failed = 1;
|
p->failed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
unsigned int jtag_set_breakpoint( struct jtdev *p,int bp_num, address_t bp_addr )
|
||||||
|
{
|
||||||
|
/* The breakpoint logic is explained in 'SLAU414c EEM.pdf' */
|
||||||
|
/* A good overview is given with Figure 1-1 */
|
||||||
|
/* MBx is TBx in EEM_defs.h */
|
||||||
|
/* CPU Stop is BREAKREACT in EEM_defs.h */
|
||||||
|
/* State Storage is STOR_REACT in EEM_defs.h */
|
||||||
|
/* Cycle Counter is EVENT_REACT in EEM_defs.h */
|
||||||
|
|
||||||
|
unsigned int breakreact;
|
||||||
|
|
||||||
|
if (bp_num >= 8) {
|
||||||
|
/* there are no more than 8 breakpoints in EEM */
|
||||||
|
printc_err("jtag_set_breakpoint: failed setting "
|
||||||
|
"breakpoint %d at %04x\n", bp_num, bp_addr);
|
||||||
|
p->failed = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bp_num < 0) {
|
||||||
|
/* disable all breakpoints by deleting the BREAKREACT
|
||||||
|
* register */
|
||||||
|
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE);
|
||||||
|
jtag_dr_shift(p, BREAKREACT + WRITE);
|
||||||
|
jtag_dr_shift(p, 0x0000);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set breakpoint */
|
||||||
|
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE);
|
||||||
|
jtag_dr_shift(p, GENCTRL + WRITE);
|
||||||
|
jtag_dr_shift(p, EEM_EN + CLEAR_STOP + EMU_CLK_EN + EMU_FEAT_EN);
|
||||||
|
|
||||||
|
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
|
||||||
|
jtag_dr_shift(p, 8*bp_num + MBTRIGxVAL + WRITE);
|
||||||
|
jtag_dr_shift(p, bp_addr);
|
||||||
|
|
||||||
|
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
|
||||||
|
jtag_dr_shift(p, 8*bp_num + MBTRIGxCTL + WRITE);
|
||||||
|
jtag_dr_shift(p, MAB + TRIG_0 + CMP_EQUAL);
|
||||||
|
|
||||||
|
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
|
||||||
|
jtag_dr_shift(p, 8*bp_num + MBTRIGxMSK + WRITE);
|
||||||
|
jtag_dr_shift(p, NO_MASK);
|
||||||
|
|
||||||
|
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
|
||||||
|
jtag_dr_shift(p, 8*bp_num + MBTRIGxCMB + WRITE);
|
||||||
|
jtag_dr_shift(p, 1<<bp_num);
|
||||||
|
|
||||||
|
/* read the actual setting of the BREAKREACT register */
|
||||||
|
/* while reading a 1 is automatically shifted into LSB */
|
||||||
|
/* this will be undone and the bit for the new breakpoint set */
|
||||||
|
/* then the updated value is stored back */
|
||||||
|
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
|
||||||
|
breakreact = jtag_dr_shift(p, BREAKREACT + READ);
|
||||||
|
breakreact += jtag_dr_shift(p, 0x000);
|
||||||
|
breakreact = (breakreact >> 1) | (1 << bp_num);
|
||||||
|
jtag_dr_shift(p, BREAKREACT + WRITE);
|
||||||
|
jtag_dr_shift(p, breakreact);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
unsigned int jtag_cpu_state( struct jtdev *p )
|
||||||
|
{
|
||||||
|
jtag_ir_shift(p, IR_EMEX_READ_CONTROL);
|
||||||
|
|
||||||
|
if ((jtag_dr_shift(p, 0x0000) & 0x0080) == 0x0080) {
|
||||||
|
return 1; /* halted */
|
||||||
|
} else {
|
||||||
|
return 0; /* running */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* MSPDebug - debugging tool for MSP430 MCUs
|
/* MSPDebug - debugging tool for MSP430 MCUs
|
||||||
* Copyright (C) 2009-2012 Daniel Beer
|
* Copyright (C) 2009-2012 Daniel Beer
|
||||||
* Copyright (C) 2012-2014 Peter Bägel
|
* Copyright (C) 2012-2015 Peter Bägel
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,10 +18,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* jtag functions are taken from TIs SLAA149–September 2002
|
/* jtag functions are taken from TIs SLAA149–September 2002
|
||||||
|
*
|
||||||
|
* breakpoint implementation influenced by a posting of Ruisheng Lin
|
||||||
|
* to Travis Goodspeed at 2012-09-20 found at:
|
||||||
|
* http://sourceforge.net/p/goodfet/mailman/message/29860790/
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* 2012-10-03 Peter Bägel (DF5EQ)
|
* 2012-10-03 Peter Bägel (DF5EQ)
|
||||||
* 2012-10-03 initial release Peter Bägel (DF5EQ)
|
* 2012-10-03 initial release Peter Bägel (DF5EQ)
|
||||||
* 2014-12-26 jtag_single_step added Peter Bägel (DF5EQ)
|
* 2014-12-26 jtag_single_step added Peter Bägel (DF5EQ)
|
||||||
|
* 2015-02-21 jtag_set_breakpoint added Peter Bägel (DF5EQ)
|
||||||
|
* jtag_cpu_state added
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef JTAGLIB_H_
|
#ifndef JTAGLIB_H_
|
||||||
|
@ -105,5 +112,8 @@ address_t jtag_read_reg(struct jtdev *p, int reg);
|
||||||
/* Writes a value into a register of the target CPU */
|
/* Writes a value into a register of the target CPU */
|
||||||
void jtag_write_reg(struct jtdev *p, int reg, address_t value);
|
void jtag_write_reg(struct jtdev *p, int reg, address_t value);
|
||||||
void jtag_single_step(struct jtdev *p);
|
void jtag_single_step(struct jtdev *p);
|
||||||
|
unsigned int jtag_set_breakpoint(struct jtdev *p,
|
||||||
|
int bp_num, address_t bp_addr);
|
||||||
|
unsigned int jtag_cpu_state(struct jtdev *p);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* MSPDebug - debugging tool for MSP430 MCUs
|
/* MSPDebug - debugging tool for MSP430 MCUs
|
||||||
* Copyright (C) 2009-2012 Daniel Beer
|
* Copyright (C) 2009-2012 Daniel Beer
|
||||||
* Copyright (C) 2012-2014 Peter Bägel
|
* Copyright (C) 2012-2015 Peter Bägel
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,8 +20,9 @@
|
||||||
/* Driver for parallel port interface like the Olimex MSP430-JTAG
|
/* Driver for parallel port interface like the Olimex MSP430-JTAG
|
||||||
* Starting point was the goodfet driver
|
* Starting point was the goodfet driver
|
||||||
*
|
*
|
||||||
* 2012-10-03 Peter Bägel (DF5EQ)
|
* 2012-10-03 initial release Peter Bägel (DF5EQ)
|
||||||
* 2014-12-26 single step implemented Peter Bägel (DF5EQ)
|
* 2014-12-26 single step implemented Peter Bägel (DF5EQ)
|
||||||
|
* 2015-02-21 breakpoints implemented Peter Bägel (DF5EQ)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -147,6 +148,43 @@ struct pif_device {
|
||||||
struct jtdev jtag;
|
struct jtdev jtag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int refresh_bps(struct pif_device *dev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
struct device_breakpoint *bp;
|
||||||
|
address_t addr;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < dev->base.max_breakpoints; i++) {
|
||||||
|
bp = &dev->base.breakpoints[i];
|
||||||
|
|
||||||
|
printc_dbg("refresh breakpoint %d: type=%d "
|
||||||
|
"addr=%04x flags=%04x\n",
|
||||||
|
i, bp->type, bp->addr, bp->flags);
|
||||||
|
|
||||||
|
if ( (bp->flags & DEVICE_BP_DIRTY) &&
|
||||||
|
(bp->type == DEVICE_BPTYPE_BREAK) ) {
|
||||||
|
addr = bp->addr;
|
||||||
|
|
||||||
|
if ( !(bp->flags & DEVICE_BP_ENABLED) ) {
|
||||||
|
addr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jtag_set_breakpoint (&dev->jtag, i, addr) == 0) {
|
||||||
|
printc_err("pif: failed to refresh "
|
||||||
|
"breakpoint #%d\n", i);
|
||||||
|
ret = -1;
|
||||||
|
} else {
|
||||||
|
bp->flags &= ~DEVICE_BP_DIRTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
static int pif_readmem( device_t dev_base,
|
static int pif_readmem( device_t dev_base,
|
||||||
address_t addr,
|
address_t addr,
|
||||||
|
@ -278,6 +316,10 @@ static int pif_ctl(device_t dev_base, device_ctl_t type)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEVICE_CTL_RUN:
|
case DEVICE_CTL_RUN:
|
||||||
|
/* transfer changed breakpoints to device */
|
||||||
|
if (refresh_bps(dev) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/* start program execution at current PC */
|
/* start program execution at current PC */
|
||||||
jtag_release_device(&dev->jtag, 0xffff);
|
jtag_release_device(&dev->jtag, 0xffff);
|
||||||
break;
|
break;
|
||||||
|
@ -303,9 +345,15 @@ static int pif_ctl(device_t dev_base, device_ctl_t type)
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
static device_status_t pif_poll(device_t dev_base)
|
static device_status_t pif_poll(device_t dev_base)
|
||||||
{
|
{
|
||||||
if (delay_ms(100) < 0)
|
struct pif_device *dev = (struct pif_device *)dev_base;
|
||||||
|
|
||||||
|
if (delay_ms(100) < 0 || ctrlc_check())
|
||||||
return DEVICE_STATUS_INTR;
|
return DEVICE_STATUS_INTR;
|
||||||
|
|
||||||
|
if (jtag_cpu_state(&dev->jtag) == 1) {
|
||||||
|
return DEVICE_STATUS_HALTED;
|
||||||
|
}
|
||||||
|
|
||||||
return DEVICE_STATUS_RUNNING;
|
return DEVICE_STATUS_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +408,7 @@ static device_t pif_open(const struct device_args *args)
|
||||||
|
|
||||||
memset(dev, 0, sizeof(*dev));
|
memset(dev, 0, sizeof(*dev));
|
||||||
dev->base.type = &device_pif;
|
dev->base.type = &device_pif;
|
||||||
dev->base.max_breakpoints = 0;
|
dev->base.max_breakpoints = 2; //supported by all devices
|
||||||
(&dev->jtag)->f = &jtdev_func_pif;
|
(&dev->jtag)->f = &jtdev_func_pif;
|
||||||
|
|
||||||
if ((&dev->jtag)->f->jtdev_open(&dev->jtag, args->path) < 0) {
|
if ((&dev->jtag)->f->jtdev_open(&dev->jtag, args->path) < 0) {
|
||||||
|
|
Loading…
Reference in New Issue