diff options
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | doc/openocd.texi | 103 | ||||
-rw-r--r-- | src/flash/flash.c | 28 | ||||
-rw-r--r-- | src/flash/flash.h | 1 | ||||
-rw-r--r-- | src/helper/command.c | 50 | ||||
-rw-r--r-- | src/jtag/usbprog.c | 598 | ||||
-rw-r--r-- | src/server/Makefile.am | 2 | ||||
-rw-r--r-- | src/server/gdb_server.c | 330 | ||||
-rw-r--r-- | src/server/gdb_server.h | 1 | ||||
-rw-r--r-- | src/target/image.c | 41 | ||||
-rw-r--r-- | src/target/target.c | 7 | ||||
-rw-r--r-- | src/target/target.h | 2 |
12 files changed, 791 insertions, 373 deletions
diff --git a/configure.in b/configure.in index 3802f60a..fd2584bb 100644 --- a/configure.in +++ b/configure.in @@ -1,3 +1,4 @@ +AC_PREREQ(2.59) AC_INIT(configure.in) AC_SEARCH_LIBS([ioperm], [ioperm]) diff --git a/doc/openocd.texi b/doc/openocd.texi index bb2c9435..786af94b 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -30,6 +30,7 @@ This is edition @value{EDITION} of the openocd manual for version * Configuration:: Openocd Configuration. * Commands:: Openocd Commands * Sample Scripts:: Sample Target Scripts +* GDB and Openocd:: Using GDB and Openocd * FAQ:: Frequently Asked Questions * License:: GNU Free Documentation License * Index:: Main index. @@ -194,6 +195,22 @@ Port on which to listen for incoming telnet connections @cindex gdb_port First port on which to listen for incoming GDB connections. The GDB port for the first target will be gdb_port, the second target will listen on gdb_port + 1, and so on. +@item @b{gdb_detach} <@var{resume|reset|halt|nothing}> +@cindex gdb_detach +Configures what openocd will do when gdb detaches from the daeman. +Default behaviour is <@var{resume}> +@item @b{gdb_memory_map} <@var{enable|disable}> +@cindex gdb_memory_map +Set to <@var{enable}> so that openocd will send the memory configuration to gdb when +requested. gdb will then know when to set hardware breakpoints, and program flash +using the gdb load command. @option{gdb_flash_program enable} will also need enabling +for flash programming to work. +Default behaviour is <@var{disable}> +@item @b{gdb_flash_program} <@var{enable|disable}> +@cindex gdb_flash_program +Set to <@var{enable}> so that openocd will program the flash memory when a +vFlash packet is received. +Default behaviour is <@var{disable}> @item @b{daemon_startup} <@var{mode}> either @samp{attach} or @samp{reset} @cindex daemon_startup Tells the OpenOCD whether it should reset the target when the daemon is launched, or @@ -441,8 +458,9 @@ unavailable for some time during startup (like the STR7 series), you can't use @item @b{target_script} <@var{target#}> <@var{event}> <@var{script_file}> @cindex target_script -Event is either @var{reset} or @var{post_halt} or @var{pre_resume}. -TODO: describe exact semantic of events +Event is either @option{reset}, @option{post_halt}, @option{pre_resume} or @option{gdb_program_config} + +TODO: describe exact semantic of events @item @b{run_and_halt_time} <@var{target#}> <@var{time_in_ms}> @cindex run_and_halt_time The amount of time the debugger should wait after releasing reset before it asserts @@ -866,8 +884,8 @@ mass erase flash memory. @end itemize @page -@section Arcitecture Specific Commands -@cindex Arcitecture Specific Commands +@section Architecture Specific Commands +@cindex Architecture Specific Commands @subsection ARMV4/5 specific commands @cindex ARMV4/5 specific commands @@ -1014,7 +1032,7 @@ This page will collect some script examples for different CPUs. The configuration script can be divided in the following section: @itemize @bullet -@item deamon configuration +@item daemon configuration @item interface @item jtag scan chain @item target configuration @@ -1025,9 +1043,9 @@ Detailed information about each section can be found at OpenOCD configuration @section OMAP5912 Flash Debug @cindex OMAP5912 Flash Debug -The following two scripts was used with an wiggler PP and and a TI OMAP5912 -dual core processor (@uref{http://www.ti.com}) on a OMAP5912 OSK board -(@uref{http://www.spectrumdigital.com}). +The following two scripts were used with a wiggler PP and and a TI OMAP5912 +dual core processor - (@uref{http://www.ti.com}), on a OMAP5912 OSK board +- (@uref{http://www.spectrumdigital.com}). @subsection Openocd config @smallexample #daemon configuration @@ -1280,7 +1298,7 @@ run_and_halt_time 0 30 working_area 0 0x20000000 16384 nobackup #flash bank <driver> <base> <size> <chip_width> <bus_width> -flash bank stm32x 0x08000000 0x00010000 0 0 0 +flash bank stm32x 0x08000000 0x00020000 0 0 0 @end smallexample @section STM32x Performance Stick @@ -1320,7 +1338,7 @@ run_and_halt_time 0 30 working_area 0 0x20000000 16384 nobackup #flash bank <driver> <base> <size> <chip_width> <bus_width> -flash bank stm32x 0x08000000 0x00010000 0 0 0 +flash bank stm32x 0x08000000 0x00020000 0 0 0 @end smallexample @section LPC2129 Script @@ -1673,6 +1691,71 @@ run_and_halt_time 0 30 flash bank cfi 0x00000000 0x1000000 2 4 0 @end smallexample +@node GDB and Openocd +@chapter GDB and Openocd +@cindex GDB and Openocd +Openocd complies with the remote gdbserver protocol, and as such can be used +to debug remote targets. + +@section Connecting to gdb +@cindex Connecting to gdb +A connection is typically started as follows: +@smallexample +target remote localhost:3333 +@end smallexample +This would cause gdb to connect to the gdbserver on the local pc using port 3333. + +To see a list of available openocd commands type @option{monitor help} on the +gdb commandline. + +Openocd supports the gdb @option{qSupported} packet, this enables information +to be sent by the gdb server (openocd) to gdb. Typical information includes +packet size and device memory map. + +Previous versions of openocd required the following gdb options to increase +the packet size and speed up gdb communication. +@smallexample +set remote memory-write-packet-size 1024 +set remote memory-write-packet-size fixed +set remote memory-read-packet-size 1024 +set remote memory-read-packet-size fixed +@end smallexample +This is now handled in the @option{qSupported} PacketSize. + +@section Programming using gdb +@cindex Programming using gdb + +By default the target memory map is not sent to gdb, this can be enabled by +the following openocd config option: +@smallexample +gdb_memory_map enable +@end smallexample +For this to function correctly a valid flash config must also be configured +in openocd. For speed also configure a valid working area. + +Informing gdb of the memory map of the target will enable gdb to protect any +flash area of the target and use hardware breakpoints by default. This means +that the openocd option @option{arm7_9 force_hw_bkpts} is not required when +using a memory map. + +To view the configured memory map in gdb, use the gdb command @option{info mem} +All other unasigned addresses within gdb are treated as ram. + +If @option{gdb_flash_program enable} is also used, gdb will be able to +program any flash memory using the vFlash interface. + +gdb will look at the target memory map when a load command is given, if any +areas to be programmed lie within the target flash area the vFlash packets +will be used. + +Incase the target needs configuring before gdb programming, a script can be executed. +@smallexample +target_script 0 gdb_program_config config.script +@end smallexample + +To verify any flash programming the gdb command @option{compare-sections} +can be used. + @node FAQ @chapter FAQ @cindex faq diff --git a/src/flash/flash.c b/src/flash/flash.c index efd16c34..de42fcde 100644 --- a/src/flash/flash.c +++ b/src/flash/flash.c @@ -393,6 +393,9 @@ int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char * return ERROR_INVALID_ARGUMENTS; } + /* We can't know if we did a resume + halt, in which case we no longer know the erased state */ + flash_set_dirty(); + duration_start_measure(&duration); if ((retval = flash_erase(target, address, length)) != ERROR_OK) @@ -766,6 +769,21 @@ int handle_flash_write_binary_command(struct command_context_s *cmd_ctx, char *c return ERROR_OK; } +void flash_set_dirty(void) +{ + flash_bank_t *c; + int i; + + /* set all flash to require erasing */ + for (c = flash_banks; c; c = c->next) + { + for (i = 0; i < c->num_sectors; i++) + { + c->sectors[i].is_erased = 0; + } + } +} + /* lookup flash bank by address */ flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr) { @@ -852,14 +870,8 @@ int flash_write(target_t *target, image_t *image, u32 *written, char **error_str { /* assume all sectors need erasing - stops any problems * when flash_write is called multiple times */ - - for (c = flash_banks; c; c = c->next) - { - for (i = 0; i < c->num_sectors; i++) - { - c->sectors[i].is_erased = 0; - } - } + + flash_set_dirty(); } /* loop until we reach end of the image */ diff --git a/src/flash/flash.h b/src/flash/flash.h index e8f91500..0f616a9a 100644 --- a/src/flash/flash.h +++ b/src/flash/flash.h @@ -68,6 +68,7 @@ extern int flash_init(struct command_context_s *cmd_ctx); extern int flash_erase(target_t *target, u32 addr, u32 length); extern int flash_write(target_t *target, image_t *image, u32 *written, char **error, int *failed, int erase); +extern void flash_set_dirty(void); extern flash_bank_t *get_flash_bank_by_num(int num); extern flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr); diff --git a/src/helper/command.c b/src/helper/command.c index 44ead7cb..adaad109 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -200,25 +200,24 @@ int parse_line(char *line, char *words[], int max_words) /* we're inside a word or quote, and reached its end*/ if (word_start) { - int len; - char *word_end=p; - /* This will handle extra whitespace within quotes */ - while (isspace(*word_start)&&(word_start<word_end)) - word_start++; - while (isspace(*(word_end-1))&&(word_start<word_end)) - word_end--; - - len = word_end - word_start; - - if (len>0) - { - /* copy the word */ - memcpy(words[nwords] = malloc(len + 1), word_start, len); - /* add terminating NUL */ - words[nwords++][len] = 0; - } + int len; + char *word_end=p; + + /* This will handle extra whitespace within quotes */ + while (isspace(*word_start)&&(word_start<word_end)) + word_start++; + while (isspace(*(word_end-1))&&(word_start<word_end)) + word_end--; + len = word_end - word_start; + + if (len>0) + { + /* copy the word */ + memcpy(words[nwords] = malloc(len + 1), word_start, len); + /* add terminating NUL */ + words[nwords++][len] = 0; + } } - /* we're done parsing the line */ if (!*p) break; @@ -226,9 +225,9 @@ int parse_line(char *line, char *words[], int max_words) /* skip over trailing quote or whitespace*/ if (inquote || isspace(*p)) p++; - while (isspace(*p)) - p++; - + while (isspace(*p)) + p++; + inquote = 0; word_start = 0; } @@ -267,14 +266,23 @@ void command_print(command_context_t *context, char *format, ...) { /* increase buffer until it fits the whole string */ if (!(p = realloc(buffer, size += 4096))) + { + /* gotta free up */ + if (buffer) + free(buffer); return; + } buffer = p; } /* vsnprintf failed */ if (n < 0) + { + if (buffer) + free(buffer); return; + } p = buffer; diff --git a/src/jtag/usbprog.c b/src/jtag/usbprog.c index 94be8777..661b3b34 100644 --- a/src/jtag/usbprog.c +++ b/src/jtag/usbprog.c @@ -1,14 +1,14 @@ /*************************************************************************** - * Copyright (C) 2007 by Benedikt Sauter sauter@ixbat.de * - * based on Dominic Rath's amt_jtagaccel.c * - * * - * usbprog is a free programming adapter. You can easily install * - * different firmware versions from an "online pool" over USB. * - * The adapter can be used for programming and debugging AVR and ARM * - * processors, as USB to RS232 converter, as JTAG interface or as * - * simple I/O interface (5 lines). * - * * - * http://www.embedded-projects.net/usbprog * + * Copyright (C) 2007 by Benedikt Sauter sauter@ixbat.de * + * based on Dominic Rath's amt_jtagaccel.c * + * * + * usbprog is a free programming adapter. You can easily install * + * different firmware versions from an "online pool" over USB. * + * The adapter can be used for programming and debugging AVR and ARM * + * processors, as USB to RS232 converter, as JTAG interface or as * + * simple I/O interface (5 lines). * + * * + * http://www.embedded-projects.net/usbprog * * * * 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 * @@ -42,7 +42,7 @@ #define VID 0x1781 #define PID 0x0c63 -// Pins at usbprog +/* Pins at usbprog */ #define TDO_BIT 0 #define TDI_BIT 3 #define TCK_BIT 2 @@ -54,7 +54,6 @@ int usbprog_register_commands(struct command_context_s *cmd_ctx); int usbprog_init(void); int usbprog_quit(void); - void usbprog_end_state(enum tap_state state); void usbprog_state_move(void); void usbprog_path_move(pathmove_command_t *cmd); @@ -96,7 +95,6 @@ void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag); void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag); unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen); - void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char * buffer, int size); void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char * buffer, int size); void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffer, int size); @@ -126,111 +124,110 @@ int usbprog_register_commands(struct command_context_s *cmd_ctx) return ERROR_OK; } - int usbprog_execute_queue(void) { - jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - u8 *buffer; - - while (cmd) - { - switch (cmd->type) - { - case JTAG_END_STATE: + jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ + int scan_size; + enum scan_type type; + u8 *buffer; + + while (cmd) + { + switch (cmd->type) + { + case JTAG_END_STATE: #ifdef _DEBUG_JTAG_IO_ - DEBUG("end_state: %i", cmd->cmd.end_state->end_state); + DEBUG("end_state: %i", cmd->cmd.end_state->end_state); #endif - if (cmd->cmd.end_state->end_state != -1) - usbprog_end_state(cmd->cmd.end_state->end_state); - break; - case JTAG_RESET: + if (cmd->cmd.end_state->end_state != -1) + usbprog_end_state(cmd->cmd.end_state->end_state); + break; + case JTAG_RESET: #ifdef _DEBUG_JTAG_IO_ - DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); + DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); #endif - if (cmd->cmd.reset->trst == 1) - { - cur_state = TAP_TLR; - } - usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: + if (cmd->cmd.reset->trst == 1) + { + cur_state = TAP_TLR; + } + usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); + break; + case JTAG_RUNTEST: #ifdef _DEBUG_JTAG_IO_ - DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); + DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); #endif - if (cmd->cmd.runtest->end_state != -1) - usbprog_end_state(cmd->cmd.runtest->end_state); - usbprog_runtest(cmd->cmd.runtest->num_cycles); - break; - case JTAG_STATEMOVE: + if (cmd->cmd.runtest->end_state != -1) + usbprog_end_state(cmd->cmd.runtest->end_state); + usbprog_runtest(cmd->cmd.runtest->num_cycles); + break; + case JTAG_STATEMOVE: #ifdef _DEBUG_JTAG_IO_ - DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); + DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); #endif - if (cmd->cmd.statemove->end_state != -1) - usbprog_end_state(cmd->cmd.statemove->end_state); - usbprog_state_move(); - break; - case JTAG_PATHMOVE: + if (cmd->cmd.statemove->end_state != -1) + usbprog_end_state(cmd->cmd.statemove->end_state); + usbprog_state_move(); + break; + case JTAG_PATHMOVE: #ifdef _DEBUG_JTAG_IO_ - DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, - cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); + DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, + cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); #endif - usbprog_path_move(cmd->cmd.pathmove); - break; - case JTAG_SCAN: + usbprog_path_move(cmd->cmd.pathmove); + break; + case JTAG_SCAN: #ifdef _DEBUG_JTAG_IO_ - DEBUG("scan end in %i", cmd->cmd.scan->end_state); + DEBUG("scan end in %i", cmd->cmd.scan->end_state); #endif - if (cmd->cmd.scan->end_state != -1) - usbprog_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); - usbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - return ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); - break; - case JTAG_SLEEP: + if (cmd->cmd.scan->end_state != -1) + usbprog_end_state(cmd->cmd.scan->end_state); + scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); + type = jtag_scan_type(cmd->cmd.scan); + usbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); + if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) + return ERROR_JTAG_QUEUE_FAILED; + if (buffer) + free(buffer); + break; + case JTAG_SLEEP: #ifdef _DEBUG_JTAG_IO_ - DEBUG("sleep %i", cmd->cmd.sleep->us); + DEBUG("sleep %i", cmd->cmd.sleep->us); #endif - jtag_sleep(cmd->cmd.sleep->us); - break; - default: - ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - - return ERROR_OK; + jtag_sleep(cmd->cmd.sleep->us); + break; + default: + ERROR("BUG: unknown JTAG command type encountered"); + exit(-1); + } + + cmd = cmd->next; + } + + return ERROR_OK; } - int usbprog_init(void) { usbprog_jtag_handle = usbprog_jtag_open(); - - tms_chain_index=0; - if(usbprog_jtag_handle==0){ + + tms_chain_index = 0; + if (usbprog_jtag_handle == 0) + { ERROR("Can't find USB JTAG Interface! Please check connection and permissions."); return ERROR_JTAG_INIT_FAILED; } - + INFO("USB JTAG Interface ready!"); - + usbprog_jtag_init(usbprog_jtag_handle); usbprog_reset(0, 0); usbprog_write(0, 0, 0); - + return ERROR_OK; } int usbprog_quit(void) { - return ERROR_OK; } @@ -246,200 +243,194 @@ void usbprog_end_state(enum tap_state state) } } - -void usbprog_state_move(void) { - - int i=0, tms=0; - u8 tms_scan = TAP_MOVE(cur_state, end_state); - - usbprog_jtag_write_tms(usbprog_jtag_handle,(char)tms_scan); - for (i = 0; i < 7; i++) - { - tms = (tms_scan >> i) & 1; - } +void usbprog_state_move(void) +{ + int i = 0, tms = 0; + u8 tms_scan = TAP_MOVE(cur_state, end_state); - cur_state = end_state; + usbprog_jtag_write_tms(usbprog_jtag_handle, (char)tms_scan); + for (i = 0; i < 7; i++) + { + tms = (tms_scan >> i) & 1; + } + + cur_state = end_state; } - void usbprog_path_move(pathmove_command_t *cmd) { - int num_states = cmd->num_states; - int state_count; - - state_count = 0; - while (num_states) - { - if (tap_transitions[cur_state].low == cmd->path[state_count]) - { + int num_states = cmd->num_states; + int state_count; + + state_count = 0; + while (num_states) + { + if (tap_transitions[cur_state].low == cmd->path[state_count]) + { //INFO("1"); - usbprog_write(0, 0, 0); - usbprog_write(1, 0, 0); - } - else if (tap_transitions[cur_state].high == cmd->path[state_count]) - { + usbprog_write(0, 0, 0); + usbprog_write(1, 0, 0); + } + else if (tap_transitions[cur_state].high == cmd->path[state_count]) + { //INFO("2"); - usbprog_write(0, 1, 0); - usbprog_write(1, 1, 0); - } - else - { - ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]); - exit(-1); - } - - cur_state = cmd->path[state_count]; - state_count++; - num_states--; - } - - end_state = cur_state; + usbprog_write(0, 1, 0); + usbprog_write(1, 1, 0); + } + else + { + ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]); + exit(-1); + } + + cur_state = cmd->path[state_count]; + state_count++; + num_states--; + } + + end_state = cur_state; } - void usbprog_runtest(int num_cycles) { - int i; - - enum tap_state saved_end_state = end_state; - - + int i; + /* only do a state_move when we're not already in RTI */ - if (cur_state != TAP_RTI) - { - usbprog_end_state(TAP_RTI); - usbprog_state_move(); - } - - /* execute num_cycles */ - if(num_cycles>0) + if (cur_state != TAP_RTI) + { + usbprog_end_state(TAP_RTI); + usbprog_state_move(); + } + + /* execute num_cycles */ + if (num_cycles > 0) { usbprog_jtag_tms_send(usbprog_jtag_handle); usbprog_write(0, 0, 0); } - else { + else + { usbprog_jtag_tms_send(usbprog_jtag_handle); //INFO("NUM CYCLES %i",num_cycles); } - - for (i = 0; i < num_cycles; i++) - { - usbprog_write(1, 0, 0); - usbprog_write(0, 0, 0); - } - - /* finish in end_state */ + + for (i = 0; i < num_cycles; i++) + { + usbprog_write(1, 0, 0); + usbprog_write(0, 0, 0); + } + + /* finish in end_state */ /* - usbprog_end_state(saved_end_state); - if (cur_state != end_state) - usbprog_state_move(); + usbprog_end_state(saved_end_state); + if (cur_state != end_state) + usbprog_state_move(); */ } - - void usbprog_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) { - enum tap_state saved_end_state = end_state; - int bit_cnt; - - if (ir_scan) - usbprog_end_state(TAP_SI); - else - usbprog_end_state(TAP_SD); - + enum tap_state saved_end_state = end_state; + + if (ir_scan) + usbprog_end_state(TAP_SI); + else + usbprog_end_state(TAP_SD); + //usbprog_jtag_tms_send(usbprog_jtag_handle); - - usbprog_state_move(); - usbprog_end_state(saved_end_state); - + + usbprog_state_move(); + usbprog_end_state(saved_end_state); + usbprog_jtag_tms_send(usbprog_jtag_handle); - - if (type == SCAN_OUT) { - usbprog_jtag_write_tdi(usbprog_jtag_handle,buffer, scan_size); - } - if (type == SCAN_IN) { - usbprog_jtag_read_tdo(usbprog_jtag_handle,buffer, scan_size); - } - if (type == SCAN_IO) { - usbprog_jtag_write_and_read(usbprog_jtag_handle,buffer, scan_size); - } - - if (ir_scan) - cur_state = TAP_PI; - else - cur_state = TAP_PD; - - if (cur_state != end_state) - usbprog_state_move(); + + if (type == SCAN_OUT) + { + usbprog_jtag_write_tdi(usbprog_jtag_handle,buffer, scan_size); + } + if (type == SCAN_IN) + { + usbprog_jtag_read_tdo(usbprog_jtag_handle,buffer, scan_size); + } + if (type == SCAN_IO) + { + usbprog_jtag_write_and_read(usbprog_jtag_handle,buffer, scan_size); + } + + if (ir_scan) + cur_state = TAP_PI; + else + cur_state = TAP_PD; + + if (cur_state != end_state) + usbprog_state_move(); } /*************** jtag wrapper functions *********************/ void usbprog_write(int tck, int tms, int tdi) { - unsigned char output_value=0x00; - - if (tms) - output_value |= (1<<TMS_BIT); - if (tdi) - output_value |= (1<<TDI_BIT); - if (tck) - output_value |= (1<<TCK_BIT); - - usbprog_jtag_write_slice(usbprog_jtag_handle,output_value); + unsigned char output_value=0x00; + + if (tms) + output_value |= (1<<TMS_BIT); + if (tdi) + output_value |= (1<<TDI_BIT); + if (tck) + output_value |= (1<<TCK_BIT); + + usbprog_jtag_write_slice(usbprog_jtag_handle,output_value); } /* (1) assert or (0) deassert reset lines */ void usbprog_reset(int trst, int srst) { - DEBUG("trst: %i, srst: %i", trst, srst); - - if(trst) - usbprog_jtag_set_bit(usbprog_jtag_handle,5,0); - else - usbprog_jtag_set_bit(usbprog_jtag_handle,5,1); - - if(srst) - usbprog_jtag_set_bit(usbprog_jtag_handle,4,0); - else - usbprog_jtag_set_bit(usbprog_jtag_handle,4,1); + DEBUG("trst: %i, srst: %i", trst, srst); + + if (trst) + usbprog_jtag_set_bit(usbprog_jtag_handle, 5, 0); + else + usbprog_jtag_set_bit(usbprog_jtag_handle, 5, 1); + + if (srst) + usbprog_jtag_set_bit(usbprog_jtag_handle, 4, 0); + else + usbprog_jtag_set_bit(usbprog_jtag_handle, 4, 1); } - - /*************** jtag lowlevel functions ********************/ +struct usb_bus *busses; - struct usb_bus *busses; struct usbprog_jtag* usbprog_jtag_open() { - struct usb_dev_handle* usb_handle; struct usb_bus *bus; struct usb_device *dev; - - struct usbprog_jtag * tmp; - + + struct usbprog_jtag *tmp; + tmp = (struct usbprog_jtag*)malloc(sizeof(struct usbprog_jtag)); - -usb_set_debug(10); + + usb_set_debug(10); usb_init(); usb_find_busses(); usb_find_devices(); - busses = usb_get_busses(); - + /* find usbprog_jtag device in usb bus */ - - for (bus = busses; bus; bus = bus->next){ - for (dev = bus->devices; dev; dev = dev->next){ + + for (bus = busses; bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { /* condition for sucessfully hit (too bad, I only check the vendor id)*/ - if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) { + if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) + { tmp->usb_handle = usb_open(dev); - usb_set_configuration (tmp->usb_handle,1); + usb_set_configuration(tmp->usb_handle, 1); usb_claim_interface(tmp->usb_handle, 0); - usb_set_altinterface(tmp->usb_handle,0); + usb_set_altinterface(tmp->usb_handle, 0); return tmp; } } @@ -447,22 +438,22 @@ usb_set_debug(10); return 0; } - void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag) { usb_close(usbprog_jtag->usb_handle); free(usbprog_jtag); } - unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen) { - int res = usb_bulk_write(usbprog_jtag->usb_handle,3,msg,msglen,100); - if(msg[0]==2||msg[0]==1||msg[0]==4||msg[0]==0||msg[0]==6||msg[0]==0x0A||msg[0]==9) + int res = usb_bulk_write(usbprog_jtag->usb_handle, 3, msg,msglen, 100); + if ((msg[0] == 2) || (msg[0] == 1) || (msg[0] == 4) || (msg[0] == 0) || \ + (msg[0] == 6) || (msg[0] == 0x0A) || (msg[0] == 9)) return 1; - if(res == msglen) { + if (res == msglen) + { //INFO("HALLLLOOO %i",(int)msg[0]); - res = usb_bulk_read(usbprog_jtag->usb_handle,0x82, msg, 2, 100); + res = usb_bulk_read(usbprog_jtag->usb_handle, 0x82, msg, 2, 100); if (res > 0) return (unsigned char)msg[1]; else @@ -478,92 +469,103 @@ void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag) usbprog_jtag_set_direction(usbprog_jtag, 0xFE); } - void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffer, int size) { char tmp[64]; // fastes packet size for usb controller - int send_bits,bufindex=0,fillindex=0,i,j,complete=size,loops; - + int send_bits, bufindex = 0, fillindex = 0, i, loops; + char swap; // 61 byte can be transfered (488 bit) - - while(size > 0) { - if(size > 488) { + + while (size > 0) + { + if (size > 488) + { send_bits = 488; size = size - 488; loops = 61; - } else { + } + else + { send_bits = size; - loops = size/8; + loops = size / 8; loops++; size = 0; } tmp[0] = WRITE_AND_READ; - tmp[1] = (char)(send_bits>>8); // high - tmp[2] = (char)(send_bits); // low - i=0; - - for(i=0;i < loops ;i++) { - tmp[3+i]=buffer[bufindex]; + tmp[1] = (char)(send_bits >> 8); // high + tmp[2] = (char)(send_bits); // low + i = 0; + + for (i = 0; i < loops; i++) + { + tmp[3 + i] = buffer[bufindex]; bufindex++; } - - if(usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,64,1000)==64) + + if (usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 64, 1000) == 64) { //INFO("HALLLLOOO2 %i",(int)tmp[0]); usleep(1); - int timeout=0; - while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 1000) < 1){ + int timeout = 0; + while (usb_bulk_read(usbprog_jtag->usb_handle, 0x82, tmp, 64, 1000) < 1) + { timeout++; - if(timeout>10) + if (timeout > 10) break; } - - for(i=0;i<loops ;i++) { - swap = tmp[3+i]; + + for (i = 0; i < loops; i++) + { + swap = tmp[3 + i]; buffer[fillindex++] = swap; } } } } - void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char * buffer, int size) { char tmp[64]; // fastes packet size for usb controller - int send_bits,bufindex=0,fillindex=0,i,j,complete=size,loops; + int send_bits, fillindex = 0, i, loops; char swap; // 61 byte can be transfered (488 bit) - while(size > 0) { - if(size > 488) { + while (size > 0) |