disable continous polling while srst is asserted and power dropout is detected
git-svn-id: svn://svn.berlios.de/openocd/trunk@1134 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
4ad68fb6d6
commit
bbafcb3758
|
@ -1336,90 +1336,7 @@ static void zylinjtag_startNetwork()
|
|||
diag_printf("Web server running\n");
|
||||
}
|
||||
|
||||
static bool readPowerDropout()
|
||||
{
|
||||
cyg_uint32 state;
|
||||
// sample and clear power dropout
|
||||
HAL_WRITE_UINT32(0x08000010, 0x80);
|
||||
HAL_READ_UINT32(0x08000010, state);
|
||||
bool powerDropout;
|
||||
powerDropout = (state & 0x80) != 0;
|
||||
return powerDropout;
|
||||
}
|
||||
|
||||
bool readSRST()
|
||||
{
|
||||
cyg_uint32 state;
|
||||
// sample and clear SRST sensing
|
||||
HAL_WRITE_UINT32(0x08000010, 0x00000040);
|
||||
HAL_READ_UINT32(0x08000010, state);
|
||||
bool srstAsserted;
|
||||
srstAsserted = (state & 0x40) != 0;
|
||||
return srstAsserted;
|
||||
}
|
||||
|
||||
// every 300ms we check for reset & powerdropout and issue a "reset halt" if
|
||||
// so.
|
||||
|
||||
|
||||
static int sense_handler(void *priv)
|
||||
{
|
||||
struct command_context_s *cmd_ctx;
|
||||
cmd_ctx = (struct command_context_s *) priv;
|
||||
|
||||
static bool prevSrstAsserted = false;
|
||||
static bool prevPowerdropout = false;
|
||||
|
||||
bool powerDropout;
|
||||
powerDropout = readPowerDropout();
|
||||
|
||||
bool powerRestored;
|
||||
powerRestored = prevPowerdropout && !powerDropout;
|
||||
if (powerRestored)
|
||||
{
|
||||
LOG_USER("Sensed power restore.");
|
||||
}
|
||||
|
||||
cyg_tick_count_t current = cyg_current_time();
|
||||
static cyg_tick_count_t lastPower = 0;
|
||||
bool waitMore = lastPower + 200 > current;
|
||||
if (powerDropout && !waitMore)
|
||||
{
|
||||
LOG_USER("Sensed power dropout.");
|
||||
lastPower = current;
|
||||
}
|
||||
|
||||
bool srstAsserted = readSRST();
|
||||
|
||||
bool srstDeasserted;
|
||||
srstDeasserted = prevSrstAsserted && !srstAsserted;
|
||||
|
||||
static cyg_tick_count_t lastSrst = 0;
|
||||
waitMore = lastSrst + 200 > current;
|
||||
if (srstDeasserted && !waitMore)
|
||||
{
|
||||
LOG_USER("Sensed nSRST deasserted");
|
||||
lastSrst = current;
|
||||
}
|
||||
|
||||
if (!prevSrstAsserted && srstAsserted)
|
||||
{
|
||||
LOG_USER("Sensed nSRST asserted");
|
||||
}
|
||||
|
||||
prevSrstAsserted = srstAsserted;
|
||||
prevPowerdropout = powerDropout;
|
||||
|
||||
if (srstDeasserted || powerRestored)
|
||||
{
|
||||
/* Other than logging the event we can't do anything here.
|
||||
* Issuing a reset is a particularly bad idea as we might
|
||||
* be inside a reset already.
|
||||
*/
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1999,8 +1916,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
zylinjtag_parse_config_file(cmd_ctx, "/rom/openocd.cfg");
|
||||
|
||||
target_register_timer_callback(sense_handler, 200, 1, cmd_ctx);
|
||||
|
||||
// FIX!!! Yuk!
|
||||
// diag_printf() is really invoked from many more places than we trust it
|
||||
// not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
|
||||
|
|
400
src/jtag/jtag.c
400
src/jtag/jtag.c
File diff suppressed because it is too large
Load Diff
149
src/jtag/jtag.h
149
src/jtag/jtag.h
|
@ -34,16 +34,16 @@
|
|||
#endif
|
||||
|
||||
/* Tap States
|
||||
* TLR - Test-Logic-Reset, RTI - Run-Test/Idle,
|
||||
* TLR - Test-Logic-Reset, RTI - Run-Test/Idle,
|
||||
* SDS - Select-DR-Scan, CD - Capture-DR, SD - Shift-DR, E1D - Exit1-DR,
|
||||
* PD - Pause-DR, E2D - Exit2-DR, UD - Update-DR,
|
||||
* SIS - Select-IR-Scan, CI - Capture-IR, SI - Shift-IR, E1I - Exit1-IR,
|
||||
* PI - Pause-IR, E2I - Exit2-IR, UI - Update-IR
|
||||
* PI - Pause-IR, E2I - Exit2-IR, UI - Update-IR
|
||||
*/
|
||||
enum tap_state
|
||||
{
|
||||
TAP_TLR = 0x0, TAP_RTI = 0x8,
|
||||
TAP_SDS = 0x1, TAP_CD = 0x2, TAP_SD = 0x3, TAP_E1D = 0x4,
|
||||
TAP_TLR = 0x0, TAP_RTI = 0x8,
|
||||
TAP_SDS = 0x1, TAP_CD = 0x2, TAP_SD = 0x3, TAP_E1D = 0x4,
|
||||
TAP_PD = 0x5, TAP_E2D = 0x6, TAP_UD = 0x7,
|
||||
TAP_SIS = 0x9, TAP_CI = 0xa, TAP_SI = 0xb, TAP_E1I = 0xc,
|
||||
TAP_PI = 0xd, TAP_E2I = 0xe, TAP_UI = 0xf
|
||||
|
@ -81,7 +81,7 @@ typedef struct scan_field_s
|
|||
u8 *out_mask; /* only masked bits care */
|
||||
u8 *in_value; /* pointer to a 32-bit memory location to take data scanned out */
|
||||
/* in_check_value/mask, in_handler_error_handler, in_handler_priv can be used by the in handler, otherwise they contain garbage */
|
||||
u8 *in_check_value; /* used to validate scan results */
|
||||
u8 *in_check_value; /* used to validate scan results */
|
||||
u8 *in_check_mask; /* check specified bits against check_value */
|
||||
in_handler_t in_handler; /* process received buffer using this handler */
|
||||
void *in_handler_priv; /* additional information for the in_handler */
|
||||
|
@ -187,11 +187,11 @@ enum reset_line_mode
|
|||
typedef struct jtag_interface_s
|
||||
{
|
||||
char* name;
|
||||
|
||||
|
||||
/* queued command execution
|
||||
*/
|
||||
int (*execute_queue)(void);
|
||||
|
||||
|
||||
/* interface initalization
|
||||
*/
|
||||
int (*speed)(int speed);
|
||||
|
@ -199,8 +199,8 @@ typedef struct jtag_interface_s
|
|||
int (*init)(void);
|
||||
int (*quit)(void);
|
||||
/* returns JTAG maxium speed for KHz. 0=RTCK. The function returns
|
||||
a failure if it can't support the KHz/RTCK.
|
||||
|
||||
a failure if it can't support the KHz/RTCK.
|
||||
|
||||
WARNING!!!! if RTCK is *slow* then think carefully about
|
||||
whether you actually want to support this in the driver.
|
||||
Many target scripts are written to handle the absence of RTCK
|
||||
|
@ -210,7 +210,25 @@ typedef struct jtag_interface_s
|
|||
/* returns the KHz for the provided JTAG speed. 0=RTCK. The function returns
|
||||
a failure if it can't support the KHz/RTCK. */
|
||||
int (*speed_div)(int speed, int *khz);
|
||||
|
||||
|
||||
/* Read and clear the power dropout flag. Note that a power dropout
|
||||
can be transitionary, easily much less than a ms.
|
||||
|
||||
So to find out if the power is *currently* on, you must invoke
|
||||
this method twice. Once to clear the power dropout flag and a
|
||||
second time to read the current state.
|
||||
|
||||
Currently the default implementation is never to detect power dropout.
|
||||
*/
|
||||
int (*power_dropout)(int *power_dropout);
|
||||
/* Read and clear the srst asserted detection flag.
|
||||
*
|
||||
* NB!!!! like power_dropout this does *not* read the current
|
||||
* state. srst assertion is transitionary and *can* be much
|
||||
* less than 1ms.
|
||||
*/
|
||||
int (*srst_asserted)(int *srst_asserted);
|
||||
|
||||
} jtag_interface_t;
|
||||
|
||||
enum jtag_event
|
||||
|
@ -241,10 +259,10 @@ extern int jtag_speed_post_reset;
|
|||
|
||||
enum reset_types
|
||||
{
|
||||
RESET_NONE = 0x0,
|
||||
RESET_HAS_TRST = 0x1,
|
||||
RESET_HAS_SRST = 0x2,
|
||||
RESET_TRST_AND_SRST = 0x3,
|
||||
RESET_NONE = 0x0,
|
||||
RESET_HAS_TRST = 0x1,
|
||||
RESET_HAS_SRST = 0x2,
|
||||
RESET_TRST_AND_SRST = 0x3,
|
||||
RESET_SRST_PULLS_TRST = 0x4,
|
||||
RESET_TRST_PULLS_SRST = 0x8,
|
||||
RESET_TRST_OPEN_DRAIN = 0x10,
|
||||
|
@ -253,7 +271,7 @@ enum reset_types
|
|||
|
||||
extern enum reset_types jtag_reset_config;
|
||||
|
||||
/* initialize interface upon startup. A successful no-op
|
||||
/* initialize interface upon startup. A successful no-op
|
||||
* upon subsequent invocations
|
||||
*/
|
||||
extern int jtag_interface_init(struct command_context_s *cmd_ctx);
|
||||
|
@ -266,15 +284,15 @@ extern int jtag_init_reset(struct command_context_s *cmd_ctx);
|
|||
extern int jtag_register_commands(struct command_context_s *cmd_ctx);
|
||||
|
||||
/* JTAG interface, can be implemented with a software or hardware fifo
|
||||
*
|
||||
*
|
||||
* TAP_SD and TAP_SI are illegal end states. TAP_SD/SI as end states
|
||||
* can be emulated by using a larger scan.
|
||||
*
|
||||
* Code that is relatively insensitive to the path(as long
|
||||
* as it is JTAG compliant) taken through state machine can use
|
||||
* endstate for jtag_add_xxx_scan(). Otherwise the pause state must be
|
||||
* specified as end state and a subsequent jtag_add_pathmove() must
|
||||
* be issued.
|
||||
* as it is JTAG compliant) taken through state machine can use
|
||||
* endstate for jtag_add_xxx_scan(). Otherwise the pause state must be
|
||||
* specified as end state and a subsequent jtag_add_pathmove() must
|
||||
* be issued.
|
||||
*
|
||||
*/
|
||||
extern void jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate);
|
||||
|
@ -291,25 +309,25 @@ extern int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields
|
|||
extern void jtag_add_tlr(void);
|
||||
extern int interface_jtag_add_tlr(void);
|
||||
/* Do not use jtag_add_pathmove() unless you need to, but do use it
|
||||
* if you have to.
|
||||
* if you have to.
|
||||
*
|
||||
* DANGER! If the target is dependent upon a particular sequence
|
||||
* of transitions for things to work correctly(e.g. as a workaround
|
||||
* for an errata that contradicts the JTAG standard), then pathmove
|
||||
* must be used, even if some jtag interfaces happen to use the
|
||||
* desired path. Worse, the jtag interface used for testing a
|
||||
* particular implementation, could happen to use the "desired"
|
||||
* of transitions for things to work correctly(e.g. as a workaround
|
||||
* for an errata that contradicts the JTAG standard), then pathmove
|
||||
* must be used, even if some jtag interfaces happen to use the
|
||||
* desired path. Worse, the jtag interface used for testing a
|
||||
* particular implementation, could happen to use the "desired"
|
||||
* path when transitioning to/from end
|
||||
* state.
|
||||
*
|
||||
* A list of unambigious single clock state transitions, not
|
||||
* all drivers can support this, but it is required for e.g.
|
||||
* XScale and Xilinx support
|
||||
*
|
||||
*
|
||||
* Note! TAP_TLR must not be used in the path!
|
||||
*
|
||||
* Note that the first on the list must be reachable
|
||||
* via a single transition from the current state.
|
||||
*
|
||||
* Note that the first on the list must be reachable
|
||||
* via a single transition from the current state.
|
||||
*
|
||||
* All drivers are required to implement jtag_add_pathmove().
|
||||
* However, if the pathmove sequence can not be precisely
|
||||
|
@ -325,31 +343,31 @@ extern int interface_jtag_add_pathmove(int num_states, enum tap_state *path);
|
|||
/* go to TAP_RTI, if we're not already there and cycle
|
||||
* precisely num_cycles in the TAP_RTI after which move
|
||||
* to the end state, if it is != TAP_RTI
|
||||
*
|
||||
*
|
||||
* nb! num_cycles can be 0, in which case the fn will navigate
|
||||
* to endstate via TAP_RTI
|
||||
*/
|
||||
extern void jtag_add_runtest(int num_cycles, enum tap_state endstate);
|
||||
extern int interface_jtag_add_runtest(int num_cycles, enum tap_state endstate);
|
||||
/* A reset of the TAP state machine can be requested.
|
||||
*
|
||||
* Whether tms or trst reset is used depends on the capabilities of
|
||||
*
|
||||
* Whether tms or trst reset is used depends on the capabilities of
|
||||
* the target and jtag interface(reset_config command configures this).
|
||||
*
|
||||
*
|
||||
* srst can driver a reset of the TAP state machine and vice
|
||||
* versa
|
||||
*
|
||||
*
|
||||
* Application code may need to examine value of jtag_reset_config
|
||||
* to determine the proper codepath
|
||||
*
|
||||
*
|
||||
* DANGER! Even though srst drives trst, trst might not be connected to
|
||||
* the interface, and it might actually be *harmful* to assert trst in this case.
|
||||
*
|
||||
*
|
||||
* This is why combinations such as "reset_config srst_only srst_pulls_trst"
|
||||
* are supported.
|
||||
* are supported.
|
||||
*
|
||||
* only req_tlr_or_trst and srst can have a transition for a
|
||||
* call as the effects of transitioning both at the "same time"
|
||||
* call as the effects of transitioning both at the "same time"
|
||||
* are undefined, but when srst_pulls_trst or vice versa,
|
||||
* then trst & srst *must* be asserted together.
|
||||
*/
|
||||
|
@ -357,8 +375,8 @@ extern void jtag_add_reset(int req_tlr_or_trst, int srst);
|
|||
/* this drives the actual srst and trst pins. srst will always be 0
|
||||
* if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for
|
||||
* trst.
|
||||
*
|
||||
* the higher level jtag_add_reset will invoke jtag_add_tlr() if
|
||||
*
|
||||
* the higher level jtag_add_reset will invoke jtag_add_tlr() if
|
||||
* approperiate
|
||||
*/
|
||||
extern int interface_jtag_add_reset(int trst, int srst);
|
||||
|
@ -370,28 +388,31 @@ extern int interface_jtag_add_sleep(u32 us);
|
|||
|
||||
|
||||
/*
|
||||
* For software FIFO implementations, the queued commands can be executed
|
||||
* For software FIFO implementations, the queued commands can be executed
|
||||
* during this call or earlier. A sw queue might decide to push out
|
||||
* some of the jtag_add_xxx() operations once the queue is "big enough".
|
||||
*
|
||||
* This fn will return an error code if any of the prior jtag_add_xxx()
|
||||
*
|
||||
* This fn will return an error code if any of the prior jtag_add_xxx()
|
||||
* calls caused a failure, e.g. check failure. Note that it does not
|
||||
* matter if the operation was executed *before* jtag_execute_queue(),
|
||||
* jtag_execute_queue() will still return an error code.
|
||||
*
|
||||
* jtag_execute_queue() will still return an error code.
|
||||
*
|
||||
* All jtag_add_xxx() calls that have in_handler!=NULL will have been
|
||||
* executed when this fn returns, but if what has been queued only
|
||||
* clocks data out, without reading anything back, then JTAG could
|
||||
* be running *after* jtag_execute_queue() returns. The API does
|
||||
* not define a way to flush a hw FIFO that runs *after*
|
||||
* jtag_execute_queue() returns.
|
||||
*
|
||||
* jtag_add_xxx() commands can either be executed immediately or
|
||||
* at some time between the jtag_add_xxx() fn call and jtag_execute_queue().
|
||||
* executed when this fn returns, but if what has been queued only
|
||||
* clocks data out, without reading anything back, then JTAG could
|
||||
* be running *after* jtag_execute_queue() returns. The API does
|
||||
* not define a way to flush a hw FIFO that runs *after*
|
||||
* jtag_execute_queue() returns.
|
||||
*
|
||||
* jtag_add_xxx() commands can either be executed immediately or
|
||||
* at some time between the jtag_add_xxx() fn call and jtag_execute_queue().
|
||||
*/
|
||||
extern int jtag_execute_queue(void);
|
||||
/* can be implemented by hw+sw */
|
||||
extern int interface_jtag_execute_queue(void);
|
||||
extern int jtag_power_dropout(int *dropout);
|
||||
extern int jtag_srst_asserted(int *srst_asserted);
|
||||
|
||||
|
||||
/* JTAG support functions */
|
||||
extern void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler);
|
||||
|
@ -422,27 +443,27 @@ extern int jtag_verify_capture_ir;
|
|||
#ifdef HAVE_JTAG_MINIDRIVER_H
|
||||
/* Here a #define MINIDRIVER() and an inline version of hw fifo interface_jtag_add_dr_out can be defined */
|
||||
#include "jtag_minidriver.h"
|
||||
#define MINIDRIVER(a) notused ## a
|
||||
#define MINIDRIVER(a) notused ## a
|
||||
#else
|
||||
#define MINIDRIVER(a) a
|
||||
/* jtag_add_dr_out() is a faster version of jtag_add_dr_scan()
|
||||
*
|
||||
/* jtag_add_dr_out() is a faster version of jtag_add_dr_scan()
|
||||
*
|
||||
* Current or end_state can not be TAP_TLR. end_state can be -1
|
||||
*
|
||||
*
|
||||
* num_bits[i] is the number of bits to clock out from value[i] LSB first.
|
||||
*
|
||||
*
|
||||
* If the device is in bypass, then that is an error condition in
|
||||
* the caller code that is not detected by this fn, whereas jtag_add_dr_scan()
|
||||
* does detect it. Similarly if the device is not in bypass, data must
|
||||
* be passed to it.
|
||||
*
|
||||
* be passed to it.
|
||||
*
|
||||
* If anything fails, then jtag_error will be set and jtag_execute() will
|
||||
* return an error. There is no way to determine if there was a failure
|
||||
* during this function call.
|
||||
*
|
||||
*
|
||||
* Note that this jtag_add_dr_out can be defined as an inline function.
|
||||
*/
|
||||
extern void interface_jtag_add_dr_out(int device,
|
||||
extern void interface_jtag_add_dr_out(int device,
|
||||
int num_fields,
|
||||
const int *num_bits,
|
||||
const u32 *value,
|
||||
|
@ -452,7 +473,7 @@ extern void interface_jtag_add_dr_out(int device,
|
|||
|
||||
|
||||
|
||||
static __inline__ void jtag_add_dr_out(int device,
|
||||
static __inline__ void jtag_add_dr_out(int device,
|
||||
int num_fields,
|
||||
const int *num_bits,
|
||||
const u32 *value,
|
||||
|
|
|
@ -39,20 +39,20 @@ extern int jtag_error;
|
|||
|
||||
/* low level command set
|
||||
*/
|
||||
int eCosBoard_read(void);
|
||||
static void eCosBoard_write(int tck, int tms, int tdi);
|
||||
void eCosBoard_reset(int trst, int srst);
|
||||
int zy1000_read(void);
|
||||
static void zy1000_write(int tck, int tms, int tdi);
|
||||
void zy1000_reset(int trst, int srst);
|
||||
|
||||
|
||||
int eCosBoard_speed(int speed);
|
||||
int eCosBoard_register_commands(struct command_context_s *cmd_ctx);
|
||||
int eCosBoard_init(void);
|
||||
int eCosBoard_quit(void);
|
||||
int zy1000_speed(int speed);
|
||||
int zy1000_register_commands(struct command_context_s *cmd_ctx);
|
||||
int zy1000_init(void);
|
||||
int zy1000_quit(void);
|
||||
|
||||
/* interface commands */
|
||||
int eCosBoard_handle_eCosBoard_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
int zy1000_handle_zy1000_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
|
||||
static int eCosBoard_khz(int khz, int *jtag_speed)
|
||||
static int zy1000_khz(int khz, int *jtag_speed)
|
||||
{
|
||||
if (khz==0)
|
||||
{
|
||||
|
@ -65,7 +65,7 @@ static int eCosBoard_khz(int khz, int *jtag_speed)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int eCosBoard_speed_div(int speed, int *khz)
|
||||
static int zy1000_speed_div(int speed, int *khz)
|
||||
{
|
||||
if (speed==0)
|
||||
{
|
||||
|
@ -79,41 +79,71 @@ static int eCosBoard_speed_div(int speed, int *khz)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static bool readPowerDropout()
|
||||
{
|
||||
cyg_uint32 state;
|
||||
// sample and clear power dropout
|
||||
HAL_WRITE_UINT32(0x08000010, 0x80);
|
||||
HAL_READ_UINT32(0x08000010, state);
|
||||
bool powerDropout;
|
||||
powerDropout = (state & 0x80) != 0;
|
||||
return powerDropout;
|
||||
}
|
||||
|
||||
jtag_interface_t eCosBoard_interface =
|
||||
|
||||
static bool readSRST()
|
||||
{
|
||||
cyg_uint32 state;
|
||||
// sample and clear SRST sensing
|
||||
HAL_WRITE_UINT32(0x08000010, 0x00000040);
|
||||
HAL_READ_UINT32(0x08000010, state);
|
||||
bool srstAsserted;
|
||||
srstAsserted = (state & 0x40) != 0;
|
||||
return srstAsserted;
|
||||
}
|
||||
|
||||
static int zy1000_power_dropout(int *dropout)
|
||||
{
|
||||
*dropout=readPowerDropout(); /* by default we can't detect power dropout */
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
jtag_interface_t zy1000_interface =
|
||||
{
|
||||
.name = "ZY1000",
|
||||
.execute_queue = bitbang_execute_queue,
|
||||
.speed = eCosBoard_speed,
|
||||
.register_commands = eCosBoard_register_commands,
|
||||
.init = eCosBoard_init,
|
||||
.quit = eCosBoard_quit,
|
||||
.khz = eCosBoard_khz,
|
||||
.speed_div = eCosBoard_speed_div,
|
||||
.speed = zy1000_speed,
|
||||
.register_commands = zy1000_register_commands,
|
||||
.init = zy1000_init,
|
||||
.quit = zy1000_quit,
|
||||
.khz = zy1000_khz,
|
||||
.speed_div = zy1000_speed_div,
|
||||
.power_dropout = zy1000_power_dropout,
|
||||
};
|
||||
|
||||
bitbang_interface_t eCosBoard_bitbang =
|
||||
bitbang_interface_t zy1000_bitbang =
|
||||
{
|
||||
.read = eCosBoard_read,
|
||||
.write = eCosBoard_write,
|
||||
.reset = eCosBoard_reset
|
||||
.read = zy1000_read,
|
||||
.write = zy1000_write,
|
||||
.reset = zy1000_reset
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void eCosBoard_write(int tck, int tms, int tdi)
|
||||
static void zy1000_write(int tck, int tms, int tdi)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int eCosBoard_read(void)
|
||||
int zy1000_read(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern bool readSRST();
|
||||
|
||||
void eCosBoard_reset(int trst, int srst)
|
||||
void zy1000_reset(int trst, int srst)
|
||||
{
|
||||
LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
|
||||
if(!srst)
|
||||
|
@ -137,7 +167,7 @@ void eCosBoard_reset(int trst, int srst)
|
|||
/* assert reset */
|
||||
ZY1000_POKE(0x08000010, 0x00000002);
|
||||
}
|
||||
|
||||
|
||||
if (trst||(srst&&(jtag_reset_config & RESET_SRST_PULLS_TRST)))
|
||||
{
|
||||
waitIdle();
|
||||
|
@ -146,7 +176,7 @@ void eCosBoard_reset(int trst, int srst)
|
|||
} else
|
||||
{
|
||||
/* We'll get RCLK failure when we assert TRST, so clear any false positives here */
|
||||
ZY1000_POKE(0x08000014, 0x400);
|
||||
ZY1000_POKE(0x08000014, 0x400);
|
||||
}
|
||||
|
||||
/* wait for srst to float back up */
|
||||
|
@ -175,7 +205,7 @@ void eCosBoard_reset(int trst, int srst)
|
|||
}
|
||||
}
|
||||
|
||||
int eCosBoard_speed(int speed)
|
||||
int zy1000_speed(int speed)
|
||||
{
|
||||
if(speed == 0)
|
||||
{
|
||||
|
@ -199,26 +229,26 @@ int eCosBoard_speed(int speed)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int eCosBoard_register_commands(struct command_context_s *cmd_ctx)
|
||||
int zy1000_register_commands(struct command_context_s *cmd_ctx)
|
||||
{
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
int eCosBoard_init(void)
|
||||
int zy1000_init(void)
|
||||
{
|
||||
ZY1000_POKE(0x08000010, 0x30); // Turn on LED1 & LED2
|
||||
|
||||
/* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
|
||||
eCosBoard_reset(0, 0);
|
||||
eCosBoard_speed(jtag_speed);
|
||||
zy1000_reset(0, 0);
|
||||
zy1000_speed(jtag_speed);
|
||||
|
||||
bitbang_interface = &eCosBoard_bitbang;
|
||||
bitbang_interface = &zy1000_bitbang;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int eCosBoard_quit(void)
|
||||
int zy1000_quit(void)
|
||||
{
|
||||
|
||||
return ERROR_OK;
|
||||
|
@ -605,7 +635,7 @@ extern int jtag_ntrst_delay;
|
|||
|
||||
int interface_jtag_add_reset(int req_trst, int req_srst)
|
||||
{
|
||||
eCosBoard_reset(req_trst, req_srst);
|
||||
zy1000_reset(req_trst, req_srst);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -635,7 +665,7 @@ int interface_jtag_add_runtest(int num_cycles, enum tap_state state)
|
|||
/* test manual drive code on any target */
|
||||
int tms;
|
||||
u8 tms_scan = TAP_MOVE(t, state);
|
||||
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
tms = (tms_scan >> i) & 1;
|
||||
|
@ -643,7 +673,7 @@ int interface_jtag_add_runtest(int num_cycles, enum tap_state state)
|
|||
ZY1000_POKE(0x08000028, tms);
|
||||
}
|
||||
waitIdle();
|
||||
ZY1000_POKE(0x08000020, state);
|
||||
ZY1000_POKE(0x08000020, state);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1447,6 +1447,71 @@ int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, ch
|
|||
}
|
||||
|
||||
|
||||
// every 300ms we check for reset & powerdropout and issue a "reset halt" if
|
||||
// so.
|
||||
|
||||
static int powerDropout;
|
||||
static int srstAsserted;
|
||||
|
||||
static int sense_handler()
|
||||
{
|
||||
static int prevSrstAsserted = 0;
|
||||
static int prevPowerdropout = 0;
|
||||
|
||||
int retval;
|
||||
if ((retval=jtag_power_dropout(&powerDropout))!=ERROR_OK)
|
||||
return retval;
|
||||
|
||||
int powerRestored;
|
||||
powerRestored = prevPowerdropout && !powerDropout;
|
||||
if (powerRestored)
|
||||
{
|
||||
LOG_USER("Sensed power restore.");
|
||||
}
|
||||
|
||||
long long current = timeval_ms();
|
||||
static long long lastPower = 0;
|
||||
int waitMore = lastPower + 2000 > current;
|
||||
if (powerDropout && !waitMore)
|
||||
{
|
||||
LOG_USER("Sensed power dropout.");
|
||||
lastPower = current;
|
||||
}
|
||||
|
||||
if ((retval=jtag_srst_asserted(&srstAsserted))!=ERROR_OK)
|
||||
return retval;
|
||||
|
||||
int srstDeasserted;
|
||||
srstDeasserted = prevSrstAsserted && !srstAsserted;
|
||||
|
||||
static long long lastSrst = 0;
|
||||
waitMore = lastSrst + 2000 > current;
|
||||
if (srstDeasserted && !waitMore)
|
||||
{
|
||||
LOG_USER("Sensed nSRST deasserted");
|
||||
lastSrst = current;
|
||||
}
|
||||
|
||||
if (!prevSrstAsserted && srstAsserted)
|
||||
{
|
||||
LOG_USER("Sensed nSRST asserted");
|
||||
}
|
||||
|
||||
prevSrstAsserted = srstAsserted;
|
||||
prevPowerdropout = powerDropout;
|
||||
|
||||
if (srstDeasserted || powerRestored)
|
||||
{
|
||||
/* Other than logging the event we can't do anything here.
|
||||
* Issuing a reset is a particularly bad idea as we might
|
||||
* be inside a reset already.
|
||||
*/
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/* process target state changes */
|
||||
int handle_target(void *priv)
|
||||
{
|
||||
|
@ -1455,7 +1520,10 @@ int handle_target(void *priv)
|
|||
|
||||
while (target)
|
||||
{
|
||||
if (target_continous_poll)
|
||||
sense_handler();
|
||||
|
||||
/* only poll target if we've got power and srst isn't asserted */
|
||||
if (target_continous_poll&&!powerDropout&&!srstAsserted)
|
||||
{
|
||||
/* polling may fail silently until the target has been examined */
|
||||
if((retval = target_poll(target)) != ERROR_OK)
|
||||
|
|
Loading…
Reference in New Issue