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__archive__
parent
4ad68fb6d6
commit
bbafcb3758
|
@ -1336,90 +1336,7 @@ static void zylinjtag_startNetwork()
|
||||||
diag_printf("Web server running\n");
|
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");
|
zylinjtag_parse_config_file(cmd_ctx, "/rom/openocd.cfg");
|
||||||
|
|
||||||
target_register_timer_callback(sense_handler, 200, 1, cmd_ctx);
|
|
||||||
|
|
||||||
// FIX!!! Yuk!
|
// FIX!!! Yuk!
|
||||||
// diag_printf() is really invoked from many more places than we trust it
|
// 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*).
|
// not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
|
||||||
|
|
|
@ -151,7 +151,7 @@ static int hasKHz = 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if BUILD_ECOSBOARD == 1
|
#if BUILD_ECOSBOARD == 1
|
||||||
extern jtag_interface_t eCosBoard_interface;
|
extern jtag_interface_t zy1000_interface;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILD_PARPORT == 1
|
#if BUILD_PARPORT == 1
|
||||||
|
@ -200,7 +200,7 @@ static int hasKHz = 0;
|
||||||
|
|
||||||
jtag_interface_t *jtag_interfaces[] = {
|
jtag_interface_t *jtag_interfaces[] = {
|
||||||
#if BUILD_ECOSBOARD == 1
|
#if BUILD_ECOSBOARD == 1
|
||||||
&eCosBoard_interface,
|
&zy1000_interface,
|
||||||
#endif
|
#endif
|
||||||
#if BUILD_PARPORT == 1
|
#if BUILD_PARPORT == 1
|
||||||
&parport_interface,
|
&parport_interface,
|
||||||
|
@ -1717,6 +1717,18 @@ static int default_speed_div(int speed, int *khz)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int default_power_dropout(int *dropout)
|
||||||
|
{
|
||||||
|
*dropout=0; /* by default we can't detect power dropout */
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int default_srst_asserted(int *srst_asserted)
|
||||||
|
{
|
||||||
|
*srst_asserted=0; /* by default we can't detect srst asserted */
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1754,6 +1766,15 @@ int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
{
|
{
|
||||||
jtag_interface->speed_div = default_speed_div;
|
jtag_interface->speed_div = default_speed_div;
|
||||||
}
|
}
|
||||||
|
if (jtag_interface->power_dropout == NULL)
|
||||||
|
{
|
||||||
|
jtag_interface->power_dropout = default_power_dropout;
|
||||||
|
}
|
||||||
|
if (jtag_interface->srst_asserted == NULL)
|
||||||
|
{
|
||||||
|
jtag_interface->srst_asserted = default_srst_asserted;
|
||||||
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2227,3 +2248,14 @@ int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int jtag_power_dropout(int *dropout)
|
||||||
|
{
|
||||||
|
return jtag->power_dropout(dropout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int jtag_srst_asserted(int *srst_asserted)
|
||||||
|
{
|
||||||
|
return jtag->srst_asserted(srst_asserted);
|
||||||
|
}
|
||||||
|
|
|
@ -211,6 +211,24 @@ typedef struct jtag_interface_s
|
||||||
a failure if it can't support the KHz/RTCK. */
|
a failure if it can't support the KHz/RTCK. */
|
||||||
int (*speed_div)(int speed, int *khz);
|
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;
|
} jtag_interface_t;
|
||||||
|
|
||||||
enum jtag_event
|
enum jtag_event
|
||||||
|
@ -392,6 +410,9 @@ extern int interface_jtag_add_sleep(u32 us);
|
||||||
extern int jtag_execute_queue(void);
|
extern int jtag_execute_queue(void);
|
||||||
/* can be implemented by hw+sw */
|
/* can be implemented by hw+sw */
|
||||||
extern int interface_jtag_execute_queue(void);
|
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 */
|
/* JTAG support functions */
|
||||||
extern void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler);
|
extern void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler);
|
||||||
|
|
|
@ -39,20 +39,20 @@ extern int jtag_error;
|
||||||
|
|
||||||
/* low level command set
|
/* low level command set
|
||||||
*/
|
*/
|
||||||
int eCosBoard_read(void);
|
int zy1000_read(void);
|
||||||
static void eCosBoard_write(int tck, int tms, int tdi);
|
static void zy1000_write(int tck, int tms, int tdi);
|
||||||
void eCosBoard_reset(int trst, int srst);
|
void zy1000_reset(int trst, int srst);
|
||||||
|
|
||||||
|
|
||||||
int eCosBoard_speed(int speed);
|
int zy1000_speed(int speed);
|
||||||
int eCosBoard_register_commands(struct command_context_s *cmd_ctx);
|
int zy1000_register_commands(struct command_context_s *cmd_ctx);
|
||||||
int eCosBoard_init(void);
|
int zy1000_init(void);
|
||||||
int eCosBoard_quit(void);
|
int zy1000_quit(void);
|
||||||
|
|
||||||
/* interface commands */
|
/* 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)
|
if (khz==0)
|
||||||
{
|
{
|
||||||
|
@ -65,7 +65,7 @@ static int eCosBoard_khz(int khz, int *jtag_speed)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eCosBoard_speed_div(int speed, int *khz)
|
static int zy1000_speed_div(int speed, int *khz)
|
||||||
{
|
{
|
||||||
if (speed==0)
|
if (speed==0)
|
||||||
{
|
{
|
||||||
|
@ -79,41 +79,71 @@ static int eCosBoard_speed_div(int speed, int *khz)
|
||||||
return ERROR_OK;
|
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",
|
.name = "ZY1000",
|
||||||
.execute_queue = bitbang_execute_queue,
|
.execute_queue = bitbang_execute_queue,
|
||||||
.speed = eCosBoard_speed,
|
.speed = zy1000_speed,
|
||||||
.register_commands = eCosBoard_register_commands,
|
.register_commands = zy1000_register_commands,
|
||||||
.init = eCosBoard_init,
|
.init = zy1000_init,
|
||||||
.quit = eCosBoard_quit,
|
.quit = zy1000_quit,
|
||||||
.khz = eCosBoard_khz,
|
.khz = zy1000_khz,
|
||||||
.speed_div = eCosBoard_speed_div,
|
.speed_div = zy1000_speed_div,
|
||||||
|
.power_dropout = zy1000_power_dropout,
|
||||||
};
|
};
|
||||||
|
|
||||||
bitbang_interface_t eCosBoard_bitbang =
|
bitbang_interface_t zy1000_bitbang =
|
||||||
{
|
{
|
||||||
.read = eCosBoard_read,
|
.read = zy1000_read,
|
||||||
.write = eCosBoard_write,
|
.write = zy1000_write,
|
||||||
.reset = eCosBoard_reset
|
.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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool readSRST();
|
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);
|
LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
|
||||||
if(!srst)
|
if(!srst)
|
||||||
|
@ -175,7 +205,7 @@ void eCosBoard_reset(int trst, int srst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int eCosBoard_speed(int speed)
|
int zy1000_speed(int speed)
|
||||||
{
|
{
|
||||||
if(speed == 0)
|
if(speed == 0)
|
||||||
{
|
{
|
||||||
|
@ -199,26 +229,26 @@ int eCosBoard_speed(int speed)
|
||||||
return ERROR_OK;
|
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;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int eCosBoard_init(void)
|
int zy1000_init(void)
|
||||||
{
|
{
|
||||||
ZY1000_POKE(0x08000010, 0x30); // Turn on LED1 & LED2
|
ZY1000_POKE(0x08000010, 0x30); // Turn on LED1 & LED2
|
||||||
|
|
||||||
/* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
|
/* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
|
||||||
eCosBoard_reset(0, 0);
|
zy1000_reset(0, 0);
|
||||||
eCosBoard_speed(jtag_speed);
|
zy1000_speed(jtag_speed);
|
||||||
|
|
||||||
bitbang_interface = &eCosBoard_bitbang;
|
bitbang_interface = &zy1000_bitbang;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int eCosBoard_quit(void)
|
int zy1000_quit(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
@ -605,7 +635,7 @@ extern int jtag_ntrst_delay;
|
||||||
|
|
||||||
int interface_jtag_add_reset(int req_trst, int req_srst)
|
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;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
/* process target state changes */
|
||||||
int handle_target(void *priv)
|
int handle_target(void *priv)
|
||||||
{
|
{
|
||||||
|
@ -1455,7 +1520,10 @@ int handle_target(void *priv)
|
||||||
|
|
||||||
while (target)
|
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 */
|
/* polling may fail silently until the target has been examined */
|
||||||
if((retval = target_poll(target)) != ERROR_OK)
|
if((retval = target_poll(target)) != ERROR_OK)
|
||||||
|
|
Loading…
Reference in New Issue