- str9x flash support (Thanks to Spencer Oliver)
[fw/openocd] / src / jtag / jtag.c
index 7c6c911a1024bce9d2c74ba9ba2f46ed51be9877..5ae7462163f4b5c2c8d2b7575b6439fcba032954 100644 (file)
@@ -124,12 +124,12 @@ jtag_event_callback_t *jtag_event_callbacks;
        extern jtag_interface_t parport_interface;
 #endif
 
-#if BUILD_FTDI2232 == 1
-       extern jtag_interface_t ftdi2232_interface;
+#if BUILD_FT2232_FTD2XX == 1
+       extern jtag_interface_t ft2232_interface;
 #endif
 
-#if BUILD_FTD2XX == 1
-       extern jtag_interface_t ftd2xx_interface;
+#if BUILD_FT2232_LIBFTDI == 1
+       extern jtag_interface_t ft2232_interface;
 #endif
 
 #if BUILD_AMTJTAGACCEL == 1
@@ -140,21 +140,28 @@ jtag_event_callback_t *jtag_event_callbacks;
        extern jtag_interface_t ep93xx_interface;
 #endif
 
+#if BUILD_AT91RM9200 == 1
+       extern jtag_interface_t at91rm9200_interface;
+#endif
+
 jtag_interface_t *jtag_interfaces[] = {
 #if BUILD_PARPORT == 1
        &parport_interface,
 #endif
-#if BUILD_FTDI2232 == 1
-       &ftdi2232_interface,
+#if BUILD_FT2232_FTD2XX == 1
+       &ft2232_interface,
 #endif
-#if BUILD_FTD2XX == 1
-       &ftd2xx_interface,
+#if BUILD_FT2232_LIBFTDI == 1
+       &ft2232_interface,
 #endif
 #if BUILD_AMTJTAGACCEL == 1
        &amt_jtagaccel_interface,
 #endif
 #if BUILD_EP93XX == 1
        &ep93xx_interface,
+#endif
+#if BUILD_AT91RM9200 == 1
+       &at91rm9200_interface,
 #endif
        NULL,
 };
@@ -694,7 +701,7 @@ int jtag_add_pathmove(int num_states, enum tap_state *path)
                return ERROR_JTAG_NOT_IMPLEMENTED;
        }
        
-       if (jtag->support_statemove)
+       if (jtag->support_pathmove)
        {
                /* allocate memory for a new list member */
                *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
@@ -843,7 +850,7 @@ int jtag_add_reset(int req_trst, int req_srst)
        {
                jtag_call_event_callbacks(JTAG_SRST_RELEASED);
                if (jtag_nsrst_delay)
-                       jtag_add_sleep(jtag_nsrst_delay);
+                       jtag_add_sleep(jtag_nsrst_delay * 1000);
        }
        
        if (trst_with_tms)
@@ -881,7 +888,7 @@ int jtag_add_reset(int req_trst, int req_srst)
                         * but we might want to add a delay to give the TAP time to settle
                         */
                        if (jtag_ntrst_delay)
-                               jtag_add_sleep(jtag_ntrst_delay);
+                               jtag_add_sleep(jtag_ntrst_delay * 1000);
                }
        }
 
@@ -951,12 +958,14 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer)
        {
                if (cmd->fields[i].out_value)
                {
-                       char* char_buf = buf_to_char(cmd->fields[i].out_value, cmd->fields[i].num_bits);
-                       buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits);
 #ifdef _DEBUG_JTAG_IO_
-                       DEBUG("fields[%i].out_value: %s", i, char_buf);
+                       char* char_buf = buf_to_str(cmd->fields[i].out_value, cmd->fields[i].num_bits, 16);
 #endif
+                       buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits);
+#ifdef _DEBUG_JTAG_IO_
+                       DEBUG("fields[%i].out_value: 0x%s", i, char_buf);
                        free(char_buf);
+#endif
                }
                
                bit_count += cmd->fields[i].num_bits;
@@ -974,20 +983,26 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
 
        for (i=0; i < cmd->num_fields; i++)
        {
-               /* if neither in_value nor in_check_value are specified we don't have to examine this field */
-               if (cmd->fields[i].in_value || cmd->fields[i].in_check_value)
+               /* if neither in_value, in_check_value nor in_handler
+                * are specified we don't have to examine this field
+                */
+               if (cmd->fields[i].in_value || cmd->fields[i].in_check_value || cmd->fields[i].in_handler)
                {
                        int num_bits = cmd->fields[i].num_bits;
+                       u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits);
+                       #ifdef _DEBUG_JTAG_IO_
+                               char *char_buf;
+
+                               char_buf = buf_to_str(captured, num_bits, 16);
+                               DEBUG("fields[%i].in_value: 0x%s", i, char_buf);
+                               free(char_buf);
+                       #endif
 
+                       
                        if (cmd->fields[i].in_value)
                        {
-                               char *char_buf;
-                               buf_set_buf(buffer, bit_count, cmd->fields[i].in_value, 0, num_bits);
-                               char_buf = buf_to_char(cmd->fields[i].in_value, num_bits);
-#ifdef _DEBUG_JTAG_IO_
-                               DEBUG("fields[%i].in_value: %s", i, char_buf);
-#endif
-                               free(char_buf);
+                               buf_cpy(captured, cmd->fields[i].in_value, num_bits);
+                               
                                if (cmd->fields[i].in_handler)
                                {
                                        if (cmd->fields[i].in_handler(cmd->fields[i].in_value, cmd->fields[i].in_handler_priv) != ERROR_OK)
@@ -998,6 +1013,18 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                                        }
                                }
                        }
+                       
+                       /* no in_value specified, but a handler takes care of the scanned data */
+                       if (cmd->fields[i].in_handler && (!cmd->fields[i].in_value))
+                       {
+                               if (cmd->fields[i].in_handler(captured, cmd->fields[i].in_handler_priv) != ERROR_OK)
+                               {
+                                       /* TODO: error reporting */
+                                       WARNING("in_handler reported a failed check");
+                                       retval = ERROR_JTAG_QUEUE_FAILED;
+                               }
+                               
+                       }
 
                        if (cmd->fields[i].in_check_value)
                        {
@@ -1005,18 +1032,18 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                                if ((cmd->fields[i].in_check_mask && buf_cmp_mask(captured, cmd->fields[i].in_check_value, cmd->fields[i].in_check_mask, num_bits))
                                        || (!cmd->fields[i].in_check_mask && buf_cmp(captured, cmd->fields[i].in_check_mask, num_bits)))
                                {
-                                       char *captured_char = buf_to_char(captured, num_bits);
-                                       char *in_check_value_char = buf_to_char(cmd->fields[i].in_check_value, num_bits);
-                                       char *in_check_mask_char = buf_to_char(cmd->fields[i].in_check_mask, num_bits);
+                                       char *captured_char = buf_to_str(captured, num_bits, 16);
+                                       char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, num_bits, 16);
+                                       char *in_check_mask_char = buf_to_str(cmd->fields[i].in_check_mask, num_bits, 16);
                                        /* TODO: error reporting */
-                                       WARNING("value captured during scan didn't pass the requested check: captured: %s check_value: %s check_mask: %s", captured_char, in_check_value_char, in_check_mask_char);
+                                       WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char);
                                        retval = ERROR_JTAG_QUEUE_FAILED;
                                        free(captured_char);
                                        free(in_check_value_char);
                                        free(in_check_mask_char);
                                }
-                               free(captured);
                        }
+                       free(captured);
                }
                bit_count += cmd->fields[i].num_bits;
        }
@@ -1031,7 +1058,7 @@ enum scan_type jtag_scan_type(scan_command_t *cmd)
        
        for (i=0; i < cmd->num_fields; i++)
        {
-               if (cmd->fields[i].in_check_value || cmd->fields[i].in_value)
+               if (cmd->fields[i].in_check_value || cmd->fields[i].in_value || cmd->fields[i].in_handler)
                        type |= SCAN_IN;
                if (cmd->fields[i].out_value)
                        type |= SCAN_OUT;
@@ -1119,7 +1146,9 @@ int jtag_validate_chain()
        {
                if (buf_get_u32(ir_test, chain_pos, 2) != 0x1)
                {
-                       ERROR("Error validating JTAG scan chain, IR mismatch");
+                       char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
+                       ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf);
+                       free(cbuf);
                        exit(-1);
                }
                chain_pos += device->ir_length;
@@ -1128,7 +1157,9 @@ int jtag_validate_chain()
        
        if (buf_get_u32(ir_test, chain_pos, 2) != 0x3)
        {
-               ERROR("Error validating JTAG scan chain, IR mismatch");
+               char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
+               ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf);
+               free(cbuf);
                exit(-1);
        }
        
@@ -1217,6 +1248,12 @@ int jtag_init(struct command_context_s *cmd_ctx)
         * didn't match one of the compiled-in interfaces
         */
        ERROR("No valid jtag interface found (%s)", jtag_interface);
+       ERROR("compiled-in jtag interfaces:");
+       for (i = 0; jtag_interfaces[i]; i++)
+       {
+               ERROR("%i: %s", i, jtag_interfaces[i]->name);
+       }
+       
        jtag = NULL;
        return ERROR_JTAG_INVALID_INTERFACE;
 }