- flash autoerase <on|off> cmd added, default is off - flash banks are calculated...
[fw/openocd] / src / jtag / usbprog.c
index 4f7cfdd65d9c78dea0c531384c49e80712f59f18..94be87777439f13d40693e2d7548d1ee055e1101 100644 (file)
@@ -1,6 +1,14 @@
 /***************************************************************************
  *   Copyright (C) 2007 by Benedikt Sauter sauter@ixbat.de                *
- *   based on Dominic Rath's usbprog.c                            *
+ *   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  *
@@ -17,6 +25,7 @@
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 #include "log.h"
 
 #define VID 0x1781
-#define PID 0x0c62
+#define PID 0x0c63
+
+// Pins at usbprog
+#define TDO_BIT         0
+#define TDI_BIT         3
+#define TCK_BIT         2
+#define TMS_BIT         1
 
 int usbprog_execute_queue(void);
 int usbprog_speed(int speed);
@@ -49,23 +64,14 @@ void usbprog_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size);
 jtag_interface_t usbprog_interface = 
 {
        .name = "usbprog",
-       
        .execute_queue = usbprog_execute_queue,
-
        .support_pathmove = 0,
-
        .speed = usbprog_speed, 
        .register_commands = usbprog_register_commands,
        .init = usbprog_init,
        .quit = usbprog_quit
 };
 
-// pins from avr
-#define TDO_BIT         0
-#define TDI_BIT         3
-#define TCK_BIT         2
-#define TMS_BIT         1
-
 #define UNKOWN_COMMAND  0x00
 #define PORT_DIRECTION  0x01
 #define PORT_SET        0x02
@@ -76,6 +82,7 @@ jtag_interface_t usbprog_interface =
 #define READ_TDO       0x07
 #define WRITE_AND_READ         0x08
 #define WRITE_TMS      0x09
+#define WRITE_TMS_CHAIN 0x0A
 
 struct usbprog_jtag 
 {
@@ -95,6 +102,11 @@ void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char * buffer, in
 void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffer, int size);
 void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan);
 
+char tms_chain[64];
+int tms_chain_index;
+void usbprog_jtag_tms_collect(char tms_scan);
+void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag);
+
 void usbprog_write(int tck, int tms, int tdi);
 void usbprog_reset(int trst, int srst);
 
@@ -201,6 +213,7 @@ int usbprog_init(void)
 {
        usbprog_jtag_handle = usbprog_jtag_open();
 
+       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;
@@ -245,11 +258,6 @@ void usbprog_state_move(void) {
                 tms = (tms_scan >> i) & 1;
         }
        
-       // moved into firmware
-       // INFO("4");
-       // koennte man in tms verlagern
-       //usbprog_write(0, tms, 0);
-
         cur_state = end_state;
 }
 
@@ -264,13 +272,13 @@ void usbprog_path_move(pathmove_command_t *cmd)
         {
                 if (tap_transitions[cur_state].low == cmd->path[state_count])
                 {
-                       INFO("1");
+                       //INFO("1");
                         usbprog_write(0, 0, 0);
                         usbprog_write(1, 0, 0);
                 }
                 else if (tap_transitions[cur_state].high == cmd->path[state_count])
                 {
-                       INFO("2");
+                       //INFO("2");
                         usbprog_write(0, 1, 0);
                         usbprog_write(1, 1, 0);
                 }
@@ -295,23 +303,27 @@ void usbprog_runtest(int num_cycles)
 
         enum tap_state saved_end_state = end_state;
 
-        /* only do a state_move when we're not already in RTI */
+
+       /* only do a state_move when we're not already in RTI */
         if (cur_state != TAP_RTI)
         {
                 usbprog_end_state(TAP_RTI);
-               //INFO("6");
                 usbprog_state_move();
         }
 
         /* execute num_cycles */
        if(num_cycles>0)
        {
-               INFO("5");
+               usbprog_jtag_tms_send(usbprog_jtag_handle);
                usbprog_write(0, 0, 0);
        }
+       else {
+               usbprog_jtag_tms_send(usbprog_jtag_handle);
+               //INFO("NUM CYCLES %i",num_cycles);
+       }
+
         for (i = 0; i < num_cycles; i++)
         {
-               INFO("3");
                 usbprog_write(1, 0, 0);
                 usbprog_write(0, 0, 0);
         }
@@ -336,10 +348,13 @@ void usbprog_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
         else
                 usbprog_end_state(TAP_SD);
 
-       //INFO("7");
+       //usbprog_jtag_tms_send(usbprog_jtag_handle);
+
         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);
         }
@@ -363,24 +378,21 @@ void usbprog_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
 
 void usbprog_write(int tck, int tms, int tdi)
 {
-        //INFO("->USBPROG SLICE");
-       //DEBUG("slice tck %i tms %i tdi %i",tck,tms,tdi);
-        unsigned char output_value=0x00;
+        unsigned char output_value=0x00;
 
-        if (tms)
+        if (tms)
                 output_value |= (1<<TMS_BIT);
-        if (tdi)
+        if (tdi)
                 output_value |= (1<<TDI_BIT);
-        if (tck)
+        if (tck)
                 output_value |= (1<<TCK_BIT);
 
-        usbprog_jtag_write_slice(usbprog_jtag_handle,output_value);
+        usbprog_jtag_write_slice(usbprog_jtag_handle,output_value);
 }
 
 /* (1) assert or (0) deassert reset lines */
 void usbprog_reset(int trst, int srst)
 {
-        //INFO("->USBPROG RESET");
         DEBUG("trst: %i, srst: %i", trst, srst);
 
         if(trst)
@@ -399,9 +411,9 @@ void usbprog_reset(int trst, int srst)
 /*************** jtag lowlevel functions ********************/
 
 
+       struct usb_bus *busses;
 struct usbprog_jtag* usbprog_jtag_open()
 {
-       struct usb_bus *busses;
        struct usb_dev_handle* usb_handle;
        struct usb_bus *bus;
        struct usb_device *dev;
@@ -410,11 +422,12 @@ struct usbprog_jtag* usbprog_jtag_open()
 
        tmp = (struct usbprog_jtag*)malloc(sizeof(struct usbprog_jtag));
 
-
+usb_set_debug(10);     
        usb_init();
        usb_find_busses();
        usb_find_devices();
 
+       
        busses = usb_get_busses();
 
        /* find usbprog_jtag device in usb bus */
@@ -424,7 +437,7 @@ struct usbprog_jtag* usbprog_jtag_open()
                        /* condition for sucessfully hit (too bad, I only check the vendor id)*/
                        if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) {
                                tmp->usb_handle = usb_open(dev);
-                               usb_set_configuration (tmp->usb_handle,dev->config[0].bConfigurationValue);
+                               usb_set_configuration (tmp->usb_handle,1);
                                usb_claim_interface(tmp->usb_handle, 0);
                                usb_set_altinterface(tmp->usb_handle,0);
                                return tmp;
@@ -445,9 +458,10 @@ void usbprog_jtag_close(struct usbprog_jtag *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)
+       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) {
+               //INFO("HALLLLOOO %i",(int)msg[0]);
                res =  usb_bulk_read(usbprog_jtag->usb_handle,0x82, msg, 2, 100);
                if (res > 0)
                        return (unsigned char)msg[1];
@@ -494,14 +508,22 @@ void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffe
                        bufindex++;
                }
     
-               usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,64,1000);
-               
-               while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 1000) < 1);
-
-               for(i=0;i<loops ;i++) {
-                       swap =  tmp[3+i];
-                       buffer[fillindex++] = swap;
-               } 
+               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){
+                               timeout++;
+                               if(timeout>10)
+                                       break;
+                       }       
+
+                       for(i=0;i<loops ;i++) {
+                               swap =  tmp[3+i];
+                               buffer[fillindex++] = swap;
+                       } 
+               }
        }
 }
 
@@ -531,7 +553,14 @@ void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char * buffer, int
     
                usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,3,1000);
     
-               while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 10) < 1);
+               //INFO("HALLLLOOO3 %i",(int)tmp[0]);
+               int timeout=0;
+               usleep(1);
+               while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 10) < 1){
+                       timeout++;
+                       if(timeout>10)
+                               break;
+               }
 
                for(i=0;i<loops ;i++) {
                        swap =  tmp[3+i];
@@ -574,10 +603,7 @@ void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char * buffer, in
 
 void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan)
 {
-       char tmp[2];    // fastes packet size for usb controller
-       tmp[0] = WRITE_TMS;
-       tmp[1] = tms_scan;
-       usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,2,1000);
+       usbprog_jtag_tms_collect(tms_scan);
 }
 
 
@@ -630,3 +656,22 @@ int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit)
                return 0;
 }
 
+void usbprog_jtag_tms_collect(char tms_scan){
+       tms_chain[tms_chain_index]=tms_scan;
+       tms_chain_index++;
+}
+
+void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag){
+       int i;
+       //INFO("TMS SEND");
+       if(tms_chain_index>0) {
+               char tmp[tms_chain_index+2];
+               tmp[0] = WRITE_TMS_CHAIN;
+               tmp[1] = (char)(tms_chain_index);
+               for(i=0;i<tms_chain_index+1;i++)
+                       tmp[2+i] = tms_chain[i];
+               usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,tms_chain_index+2,1000);
+               tms_chain_index=0;
+       }
+}
+