X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fzy1000.c;h=73a40f2ed8c5910b1ec3efd0f11cb1d6e7230100;hb=a5467296097cc0a820da3aad65dcd9de196fc1be;hp=160a51ef81a795432dd60032464217f337818b69;hpb=508ed7a7c69f74ed889e1b471929d9e68e5c1194;p=openocd.git diff --git a/src/jtag/zy1000.c b/src/jtag/zy1000.c index 160a51ef81..73a40f2ed8 100644 --- a/src/jtag/zy1000.c +++ b/src/jtag/zy1000.c @@ -20,20 +20,21 @@ #include "config.h" #endif - -#include "log.h" -#include "jtag.h" +#define INCLUDE_JTAG_INTERFACE_H +#include "embeddedice.h" +#include "minidriver.h" #include "bitbang.h" -#include "../target/embeddedice.h" - #include // low level i/o #include -#include - -extern int jtag_error; +#define ZYLIN_VERSION "1.52" +#define ZYLIN_DATE __DATE__ +#define ZYLIN_TIME __TIME__ +#define ZYLIN_OPENOCD "$Revision$" +#define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME +const char *zylin_config_dir="/config/settings"; /* low level command set */ @@ -77,7 +78,7 @@ static int zy1000_speed_div(int speed, int *khz) return ERROR_OK; } -static bool readPowerDropout() +static bool readPowerDropout(void) { cyg_uint32 state; // sample and clear power dropout @@ -89,7 +90,7 @@ static bool readPowerDropout() } -static bool readSRST() +static bool readSRST(void) { cyg_uint32 state; // sample and clear SRST sensing @@ -146,7 +147,7 @@ int zy1000_read(void) return -1; } -extern bool readSRST(); +extern bool readSRST(void); void zy1000_reset(int trst, int srst) { @@ -223,7 +224,7 @@ int zy1000_speed(int speed) { if(speed > 8190 || speed < 2) { - LOG_ERROR("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz"); + LOG_USER("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz"); return ERROR_INVALID_ARGUMENTS; } @@ -234,88 +235,149 @@ int zy1000_speed(int speed) return ERROR_OK; } -int zy1000_register_commands(struct command_context_s *cmd_ctx) +static bool savePower; + + +static void setPower(bool power) { - return ERROR_OK; + savePower = power; + if (power) + { + HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x14, 0x8); + } else + { + HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x8); + } } - -int zy1000_init(void) +int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x30); // Turn on LED1 & LED2 + if (argc > 1) + { + return ERROR_INVALID_ARGUMENTS; + } - /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */ - zy1000_reset(0, 0); - zy1000_speed(jtag_speed); + if (argc == 1) + { + if (strcmp(args[0], "on") == 0) + { + setPower(1); + } + else if (strcmp(args[0], "off") == 0) + { + setPower(0); + } else + { + command_print(cmd_ctx, "arg is \"on\" or \"off\""); + return ERROR_INVALID_ARGUMENTS; + } + } - bitbang_interface = &zy1000_bitbang; + command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off"); return ERROR_OK; } -int zy1000_quit(void) + +/* Give TELNET a way to find out what version this is */ +static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { + if ((argc < 1) || (argc > 2)) + return JIM_ERR; + char buff[128]; + const char *version_str=NULL; - return ERROR_OK; -} + if (argc == 1) + { + version_str=ZYLIN_OPENOCD_VERSION; + } else + { + const char *str = Jim_GetString(argv[1], NULL); + if (strcmp("openocd", str) == 0) + { + int revision; + revision = atol(ZYLIN_OPENOCD+strlen("XRevision: ")); + sprintf(buff, "%d", revision); + version_str=buff; + } + else if (strcmp("zy1000", str) == 0) + { + version_str=ZYLIN_VERSION; + } + else if (strcmp("date", str) == 0) + { + version_str=ZYLIN_DATE; + } + else + { + return JIM_ERR; + } + } + Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1)); + return JIM_OK; +} -/* loads a file and returns a pointer to it in memory. The file contains - * a 0 byte(sentinel) after len bytes - the length of the file. */ -int loadFile(const char *fileName, void **data, int *len) + +static int +zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp, + int argc, + Jim_Obj * const *argv) { - FILE * pFile; - pFile = fopen(fileName,"rb"); - if (pFile==NULL) - { - LOG_ERROR("Can't open %s\n", fileName); - return ERROR_JTAG_DEVICE_ERROR; - } - if (fseek(pFile, 0, SEEK_END)!=0) - { - LOG_ERROR("Can't open %s\n", fileName); - fclose(pFile); - return ERROR_JTAG_DEVICE_ERROR; - } - *len=ftell(pFile); - if (*len==-1) + if (argc != 1) { - LOG_ERROR("Can't open %s\n", fileName); - fclose(pFile); - return ERROR_JTAG_DEVICE_ERROR; + Jim_WrongNumArgs(interp, 1, argv, "powerstatus"); + return JIM_ERR; } - if (fseek(pFile, 0, SEEK_SET)!=0) - { - LOG_ERROR("Can't open %s\n", fileName); - fclose(pFile); - return ERROR_JTAG_DEVICE_ERROR; - } - *data=malloc(*len+1); - if (*data==NULL) - { - LOG_ERROR("Can't open %s\n", fileName); - fclose(pFile); - return ERROR_JTAG_DEVICE_ERROR; - } + cyg_uint32 status; + ZY1000_PEEK(ZY1000_JTAG_BASE+0x10, status); - if (fread(*data, 1, *len, pFile)!=*len) - { - fclose(pFile); - free(*data); - LOG_ERROR("Can't open %s\n", fileName); - return ERROR_JTAG_DEVICE_ERROR; - } - fclose(pFile); - *(((char *)(*data))+*len)=0; /* sentinel */ + Jim_SetResult(interp, Jim_NewIntObj(interp, (status&0x80)!=0)); + + return JIM_OK; +} + +int zy1000_register_commands(struct command_context_s *cmd_ctx) +{ + register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY, + "power - turn power switch to target on/off. No arguments - print status."); + + Jim_CreateCommand(interp, "zy1000_version", jim_zy1000_version, NULL, NULL); + + + Jim_CreateCommand(interp, "powerstatus", zylinjtag_Jim_Command_powerstatus, NULL, NULL); return ERROR_OK; +} + + + +int zy1000_init(void) +{ + LOG_USER("%s", ZYLIN_OPENOCD_VERSION); + + ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x30); // Turn on LED1 & LED2 + setPower(true); // on by default + + /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */ + zy1000_reset(0, 0); + zy1000_speed(jtag_speed); + + bitbang_interface = &zy1000_bitbang; + + return ERROR_OK; } +int zy1000_quit(void) +{ + + return ERROR_OK; +} @@ -343,7 +405,7 @@ int interface_jtag_execute_queue(void) -static cyg_uint32 getShiftValue() +static cyg_uint32 getShiftValue(void) { cyg_uint32 value; waitIdle(); @@ -352,7 +414,7 @@ static cyg_uint32 getShiftValue() return value; } #if 0 -static cyg_uint32 getShiftValueFlip() +static cyg_uint32 getShiftValueFlip(void) { cyg_uint32 value; waitIdle(); @@ -363,9 +425,9 @@ static cyg_uint32 getShiftValueFlip() #endif #if 0 -static void shiftValueInnerFlip(const enum tap_state state, const enum tap_state endState, int repeat, cyg_uint32 value) +static void shiftValueInnerFlip(const tap_state_t state, const tap_state_t endState, int repeat, cyg_uint32 value) { - VERBOSE(LOG_INFO("shiftValueInner %s %s %d %08x (flipped)", jtag_state_name(state), jtag_state_name(endState), repeat, value)); + VERBOSE(LOG_INFO("shiftValueInner %s %s %d %08x (flipped)", tap_state_name(state), tap_state_name(endState), repeat, value)); cyg_uint32 a,b; a=state; b=endState; @@ -377,12 +439,12 @@ static void shiftValueInnerFlip(const enum tap_state state, const enum tap_state extern int jtag_check_value(u8 *captured, void *priv); -static void gotoEndState() +static void gotoEndState(void) { setCurrentState(cmd_queue_end_state); } -static __inline void scanFields(int num_fields, scan_field_t *fields, enum tap_state shiftState, int pause) +static __inline void scanFields(int num_fields, scan_field_t *fields, tap_state_t shiftState, tap_state_t end_state) { int i; int j; @@ -402,31 +464,13 @@ static __inline void scanFields(int num_fields, scan_field_t *fields, enum tap_s if (fields[i].in_value!=NULL) { inBuffer=fields[i].in_value; - } else if (fields[i].in_handler!=NULL) - { - if (in_buff_size*8expected, tap->expected_mask, NULL); - } else if (jtag_verify_capture_ir) - { - fields[j].in_check_value = tap->expected; - fields[j].in_check_mask = tap->expected_mask; - } - - scanFields(1, fields+j, TAP_IRSHIFT, pause); + scanFields(1, fields+j, TAP_IRSHIFT, end_state); /* update device information */ buf_cpy(fields[j].out_value, tap->cur_instr, scan_size); @@ -538,13 +569,12 @@ int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_st memset(&tmp, 0, sizeof(tmp)); tmp.out_value = ones; tmp.num_bits = scan_size; - scanFields(1, &tmp, TAP_IRSHIFT, pause); + scanFields(1, &tmp, TAP_IRSHIFT, end_state); /* update device information */ buf_cpy(tmp.out_value, tap->cur_instr, scan_size); tap->bypass = 1; } } - gotoEndState(); return ERROR_OK; } @@ -553,17 +583,16 @@ int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_st -int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) +int interface_jtag_add_plain_ir_scan(int num_fields, const scan_field_t *fields, tap_state_t state) { - scanFields(num_fields, fields, TAP_IRSHIFT, 1); - gotoEndState(); + scanFields(num_fields, fields, TAP_IRSHIFT, cmd_queue_end_state); return ERROR_OK; } /*extern jtag_command_t **jtag_get_last_command_p(void);*/ -int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) +int interface_jtag_add_dr_scan(int num_fields, const scan_field_t *fields, tap_state_t state) { int j; @@ -572,7 +601,14 @@ int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_st { nextTap=jtag_NextEnabledTap(tap); int found=0; - int pause=(nextTap==NULL); + tap_state_t end_state; + if (nextTap==NULL) + { + end_state = cmd_queue_end_state; + } else + { + end_state = TAP_DRSHIFT; + } for (j=0; j < num_fields; j++) { @@ -580,7 +616,7 @@ int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_st { found = 1; - scanFields(1, fields+j, TAP_DRSHIFT, pause); + scanFields(1, fields+j, TAP_DRSHIFT, end_state); } } if (!found) @@ -589,27 +625,20 @@ int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_st /* program the scan field to 1 bit length, and ignore it's value */ tmp.num_bits = 1; tmp.out_value = NULL; - tmp.out_mask = NULL; tmp.in_value = NULL; - tmp.in_check_value = NULL; - tmp.in_check_mask = NULL; - tmp.in_handler = NULL; - tmp.in_handler_priv = NULL; - scanFields(1, &tmp, TAP_DRSHIFT, pause); + scanFields(1, &tmp, TAP_DRSHIFT, end_state); } else { } } - gotoEndState(); return ERROR_OK; } -int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) +int interface_jtag_add_plain_dr_scan(int num_fields, const scan_field_t *fields, tap_state_t state) { - scanFields(num_fields, fields, TAP_DRSHIFT, 1); - gotoEndState(); + scanFields(num_fields, fields, TAP_DRSHIFT, cmd_queue_end_state); return ERROR_OK; } @@ -632,10 +661,10 @@ int interface_jtag_add_reset(int req_trst, int req_srst) return ERROR_OK; } -int interface_jtag_add_runtest(int num_cycles, enum tap_state state) +static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t clockstate) { /* num_cycles can be 0 */ - setCurrentState(TAP_IDLE); + setCurrentState(clockstate); /* execute num_cycles, 32 at the time. */ int i; @@ -647,19 +676,20 @@ int interface_jtag_add_runtest(int num_cycles, enum tap_state state) { num=num_cycles-i; } - shiftValueInner(TAP_IDLE, TAP_IDLE, num, 0); + shiftValueInner(clockstate, clockstate, num, 0); } #if !TEST_MANUAL() /* finish in end_state */ setCurrentState(state); #else - enum tap_state t=TAP_IDLE; + tap_state_t t=TAP_IDLE; /* test manual drive code on any target */ int tms; - u8 tms_scan = TAP_MOVE(t, state); + u8 tms_scan = tap_get_tms_path(t, state); + int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - for (i = 0; i < 7; i++) + for (i = 0; i < tms_count; i++) { tms = (tms_scan >> i) & 1; waitIdle(); @@ -673,13 +703,23 @@ int interface_jtag_add_runtest(int num_cycles, enum tap_state state) return ERROR_OK; } +int interface_jtag_add_runtest(int num_cycles, tap_state_t state) +{ + return zy1000_jtag_add_clocks(num_cycles, state, TAP_IDLE); +} + +int interface_jtag_add_clocks(int num_cycles) +{ + return zy1000_jtag_add_clocks(num_cycles, cmd_queue_cur_state, cmd_queue_end_state); +} + int interface_jtag_add_sleep(u32 us) { jtag_sleep(us); return ERROR_OK; } -int interface_jtag_add_pathmove(int num_states, enum tap_state *path) +int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) { int state_count; int tms = 0; @@ -689,21 +729,21 @@ int interface_jtag_add_pathmove(int num_states, enum tap_state *path) state_count = 0; - enum tap_state cur_state=cmd_queue_cur_state; + tap_state_t cur_state=cmd_queue_cur_state; while (num_states) { - if (tap_transitions[cur_state].low == path[state_count]) + if (tap_state_transition(cur_state, false) == path[state_count]) { tms = 0; } - else if (tap_transitions[cur_state].high == path[state_count]) + else if (tap_state_transition(cur_state, true) == path[state_count]) { tms = 1; } else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", jtag_state_name(cur_state), jtag_state_name(path[state_count)]); + LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[state_count])); exit(-1); } @@ -725,7 +765,7 @@ int interface_jtag_add_pathmove(int num_states, enum tap_state *path) void embeddedice_write_dcc(jtag_tap_t *tap, int reg_addr, u8 *buffer, int little, int count) { // static int const reg_addr=0x5; - enum tap_state end_state=cmd_queue_end_state; + tap_state_t end_state=cmd_queue_end_state; if (jtag_NextEnabledTap(jtag_NextEnabledTap(NULL))==NULL) { /* better performance via code duplication */ @@ -760,3 +800,27 @@ void embeddedice_write_dcc(jtag_tap_t *tap, int reg_addr, u8 *buffer, int little } } +int loadFile(const char *fileName, void **data, int *len); + +/* boolean parameter stored on config */ +int boolParam(char *var) +{ + bool result = false; + char *name = alloc_printf("%s/%s", zylin_config_dir, var); + if (name == NULL) + return result; + + void *data; + int len; + if (loadFile(name, &data, &len) == ERROR_OK) + { + if (len > 1) + len = 1; + result = strncmp((char *) data, "1", len) == 0; + free(data); + } + free(name); + return result; +} + +