- reworked presto.c to allow use of either FTD2XX or libftdi (libftdi not functional...
authordrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Tue, 14 Aug 2007 09:48:54 +0000 (09:48 +0000)
committerdrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Tue, 14 Aug 2007 09:48:54 +0000 (09:48 +0000)
--enable-presto_ftd2xx and --enable-presto_libftdi
- completed trace point support for use with ARM7/9 DCC
- completed debug message output with support for HEX dumps (1, 2 or 4 byte quantities)
- fixed bug in delete_debug_msg_receiver (thanks to Pavel Chromy)
- fixed bug in image_add_section (thanks to Pavel Chromy)
- at91sam7 sector erase reworked (thanks to Pavel Chromy)
- merge consecutive sections during flash image write to work around possible section alignment issues with LPC2000 targets

git-svn-id: svn://svn.berlios.de/openocd/trunk@194 b42882b7-edfa-0310-969c-e2dbd0fdcd60

14 files changed:
configure.in
src/Makefile.am
src/flash/at91sam7.c
src/flash/flash.c
src/flash/nand.c
src/jtag/Makefile.am
src/jtag/jtag.c
src/jtag/presto.c
src/openocd.c
src/target/image.c
src/target/target.c
src/target/target_request.c
src/target/trace.c
src/target/trace.h

index 4bce9a9d4d9b24f6e7895198a305865848389573..3f3a81c408791aa208de0d1b4a13fb50e08a9902 100644 (file)
@@ -68,9 +68,13 @@ AC_ARG_ENABLE(gw16012,
   AS_HELP_STRING([--enable-gw16012], [Enable building support for the Gateworks GW16012 JTAG Programmer]),
   [build_gw16012=$enableval], [build_gw16012=no])
 
-AC_ARG_ENABLE(presto,
-  AS_HELP_STRING([--enable-presto], [Enable building support for ASIX Presto Programmer]),
-  [build_presto=$enableval], [build_presto=no])
+AC_ARG_ENABLE(presto_libftdi,
+  AS_HELP_STRING([--enable-presto_libftdi], [Enable building support for ASIX Presto Programmer using the libftdi driver]),
+  [build_presto_libftdi=$enableval], [build_presto_libftdi=no])
+
+AC_ARG_ENABLE(presto_ftd2xx,
+  AS_HELP_STRING([--enable-presto_ftd2xx], [Enable building support for ASIX Presto Programmer using the FTD2XX driver]),
+  [build_presto_ftd2xx=$enableval], [build_presto_ftd2xx=no])
 
 AC_ARG_ENABLE(usbprog,
   AS_HELP_STRING([--enable-usbprog], [Enable building support for the usbprog JTAG Programmer]),
@@ -185,11 +189,18 @@ else
   AC_DEFINE(BUILD_GW16012, 0, [0 if you don't want the Gateworks GW16012 driver.])
 fi
 
-if test $build_presto = yes; then
+if test $build_presto_libftdi = yes; then
+  build_bitq=yes
+  AC_DEFINE(BUILD_PRESTO_LIBFTDI, 1, [1 if you want the ASIX PRESTO driver using libftdi.])
+else
+  AC_DEFINE(BUILD_PRESTO_LIBFTDI, 0, [0 if you don't want the ASIX PRESTO driver using libftdi.])
+fi
+
+if test $build_presto_ftd2xx = yes; then
   build_bitq=yes
-  AC_DEFINE(BUILD_PRESTO, 1, [1 if you want the ASIX PRESTO driver.])
+  AC_DEFINE(BUILD_PRESTO_FTD2XX, 1, [1 if you want the ASIX PRESTO driver using FTD2XX.])
 else
-  AC_DEFINE(BUILD_PRESTO, 0, [0 if you don't want the ASIX PRESTO driver.])
+  AC_DEFINE(BUILD_PRESTO_FTD2XX, 0, [0 if you don't want the ASIX PRESTO driver using FTD2XX.])
 fi
 
 if test $build_bitq = yes; then
@@ -222,7 +233,8 @@ AM_CONDITIONAL(FT2232_LIBFTDI, test $build_ft2232_libftdi = yes)
 AM_CONDITIONAL(FT2232_FTD2XX, test $build_ft2232_ftd2xx = yes)
 AM_CONDITIONAL(AMTJTAGACCEL, test $build_amtjtagaccel = yes)
 AM_CONDITIONAL(GW16012, test $build_gw16012 = yes)
-AM_CONDITIONAL(PRESTO, test $build_presto = yes)
+AM_CONDITIONAL(PRESTO_LIBFTDI, test $build_presto_libftdi = yes)
+AM_CONDITIONAL(PRESTO_FTD2XX, test $build_presto_ftd2xx = yes)
 AM_CONDITIONAL(USBPROG, test $build_usbprog = yes)
 AM_CONDITIONAL(OOCD_TRACE, test $build_oocd_trace = yes)
 AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes)
index c8e7c81d3f02ae9257d4dbab3346b4e1372f3cd6..6e72a61228462f1cc7f6a36f66b76c3c25ac1f6f 100644 (file)
@@ -19,6 +19,9 @@ endif
 if FT2232_LIBFTDI
 FTDI2232LIB = -lftdi
 else
+if PRESTO_LIBFTDI
+FTDI2232LIB = -lftdi
+endif
 FTDI2232LIB =
 endif
 
@@ -41,7 +44,7 @@ endif
 if FT2232_FTD2XX
 FTD2XXLIB = $(FTD2XXLDADD)
 else
-if PRESTO
+if PRESTO_FTD2XX
 FTD2XXLIB = $(FTD2XXLDADD)
 else
 FTD2XXLIB =
index fdc1c51adefbc8791d2fdd467ce754269ce521e3..b4b347586ed9e91a4ff11a6ef9cf8671bea9a8b2 100644 (file)
@@ -326,7 +326,15 @@ int at91sam7_read_part_info(struct flash_bank_s *bank)
        at91sam7_info->cidr_version = cidr&0x001F;
        bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz];
        at91sam7_info->target_name = "Unknown";
-       
+
+       /* Support just for bulk erase of the whole device */
+       bank->num_sectors = 1;
+       bank->sectors = malloc(sizeof(flash_sector_t));
+       bank->sectors[0].offset = 0;
+       bank->sectors[0].size = bank->size;
+       bank->sectors[0].is_erased = -1;
+       bank->sectors[0].is_protected = -1;
+
        DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
 
        /* Read main and master clock freqency register */
@@ -565,22 +573,27 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
                return ERROR_FLASH_OPERATION_FAILED;
        }       
        
-       if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits))
+       if ((first < 0) || (last < first) || (last >= bank->num_sectors))
        {
-               return ERROR_FLASH_SECTOR_INVALID;
+               if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
+               {
+                       WARNING("Sector numbers based on lockbit count, probably a deprecated script");
+                       last = bank->num_sectors-1;
+               }
+               else return ERROR_FLASH_SECTOR_INVALID;
        }
 
-       /* Configure the flash controller timing */
-       at91sam7_read_clock_info(bank); 
-       at91sam7_set_flash_mode(bank,FMR_TIMING_FLASH);
-
-       if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
+       if ((first != 0) || (last != (bank->num_sectors-1)))
        {
-               return at91sam7_flash_command(bank, EA, 0);
+               WARNING("Can only erase the whole flash area, pages are autoerased on write");
+               return ERROR_FLASH_OPERATION_FAILED;
        }
 
-       WARNING("Can only erase the whole flash area, pages are autoerased on write");
-       return ERROR_FLASH_OPERATION_FAILED;
+       /* Configure the flash controller timing */
+       at91sam7_read_clock_info(bank); 
+       at91sam7_set_flash_mode(bank,FMR_TIMING_FLASH);
+
+       return at91sam7_flash_command(bank, EA, 0);
 }
 
 int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
index e3389b1938e9e22f2dd26a5a421d82bffe67d1e1..4481fc638955433527fed73d7f97c88a49ba7214 100644 (file)
@@ -738,24 +738,36 @@ int flash_erase(target_t *target, u32 addr, u32 length)
 
 int flash_write(target_t *target, image_t *image, u32 *image_size, char **error_str, u32 *failed)
 {
+       int last_section;
        int section;
+       int next_section;
        int retval;
        
        *image_size = 0;
        
        /* for each section in the image */
-       for (section = 0; section < image->num_sections; section++)
+       last_section = 0;
+       section = 0;
+       while (section < image->num_sections)
        {
                u32 offset = 0;
                u32 address = image->sections[section].base_address;
                u32 size = image->sections[section].size;
                
-               failed[section] = 0;
+               /* collect consecutive sections */
+               next_section = section + 1;
+               while ((next_section < image->num_sections)
+                               && (image->sections[next_section].base_address == (address + size)))
+               {
+                       size += image->sections[next_section].size;
+                       next_section++;
+               }
                
                while (size != 0)
                {
                        flash_bank_t *c;
                        u32 thisrun_size = size;
+                       u32 buffer_size;
                        u32 size_read;
                        u8 *buffer;
                        
@@ -767,23 +779,50 @@ int flash_write(target_t *target, image_t *image, u32 *image_size, char **error_
                                break;
                        }
                        
-                       /* check whether it fits, split into multiple runs if not */
+                       /* check whether cumulated sections fit the bank, split into multiple runs if not */
                        if ((address + size) > (c->base + c->size))
                                thisrun_size = c->base + c->size - address;
 
                        buffer = malloc(thisrun_size);
-                       if (((retval = image_read_section(image, section, offset, size, buffer, &size_read)) != ERROR_OK)
-                                       || (thisrun_size != size_read))
+                       buffer_size = 0;
+                       
+                       while (buffer_size < thisrun_size)
                        {
-                               *error_str = malloc(FLASH_MAX_ERROR_STR);
-                               snprintf(*error_str, FLASH_MAX_ERROR_STR, "error reading from image");
-                               return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
+                               u32 thissection_size = image->sections[section].size - offset;
+                               
+                               if ((retval = image_read_section(image, section, offset,
+                                               MIN(thisrun_size, thissection_size),
+                                               buffer + buffer_size, &size_read)) != ERROR_OK)
+                               {
+                                       *error_str = malloc(FLASH_MAX_ERROR_STR);
+                                       snprintf(*error_str, FLASH_MAX_ERROR_STR, "error reading from image");
+                                       return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
+                               }
+                               
+                               /* see if we're done with the current section */
+                               if (thissection_size < thisrun_size)
+                               {
+                                       /* start with the next section */
+                                       offset = 0;
+                                       failed[section] = 0;
+                                       section++;
+                               }
+                               else
+                               {
+                                       /* continue inside the current section */
+                                       offset += size_read;
+                               }
+                               
+                               buffer_size += size_read;
                        }
                        
                        if ((retval = c->driver->write(c, buffer, address - c->base, thisrun_size)) != ERROR_OK)
                        {
-                               /* mark the current section as failed */
-                               failed[section] = 1;
+                               int i;
+                               /* mark sections as failed */
+                               for (i = last_section; i <= section; i++)
+                                       failed[i] = 1;
+                               
                                *error_str = malloc(FLASH_MAX_ERROR_STR);
                                switch (retval)
                                {
@@ -817,12 +856,11 @@ int flash_write(target_t *target, image_t *image, u32 *image_size, char **error_
                        
                        free(buffer);
                        
-                       offset += thisrun_size;
                        address += thisrun_size;
                        size -= thisrun_size;
+                       *image_size += thisrun_size;
+                       last_section = section;
                }
-               
-               *image_size += image->sections[section].size;
        }
        
        return ERROR_OK;
index d06a232cc948339ba1ad51b654da0ebd101794de..52c923287ea01b4e1389edaf8e7139a58112529d 100644 (file)
@@ -256,7 +256,7 @@ int handle_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, cha
 
 int nand_register_commands(struct command_context_s *cmd_ctx)
 {
-       nand_cmd = register_command(cmd_ctx, NULL, "nand", NULL, COMMAND_ANY, NULL);
+       nand_cmd = register_command(cmd_ctx, NULL, "nand", NULL, COMMAND_ANY, "NAND specific commands");
        
        register_command(cmd_ctx, nand_cmd, "device", handle_nand_device_command, COMMAND_CONFIG, NULL);
        
index 64159e589ce841372bff726156af21b5a4d0055e..b993b1cedbf1b4d7d207f0c096186f0d0d01541d 100644 (file)
@@ -65,9 +65,12 @@ else
 BITQFILES =
 endif
 
-if PRESTO
+if PRESTO_LIBFTDI
 PRESTOFILES = presto.c
 else
+if PRESTO_FTD2XX
+PRESTOFILES = presto.c
+endif
 PRESTOFILES =
 endif
 
index bac1b39eeb07dd1d20fb3a82b633da3a13536536..5a390070bbd7879b5d1e7d159b69bff7f96d049f 100644 (file)
@@ -162,7 +162,7 @@ jtag_event_callback_t *jtag_event_callbacks;
        extern jtag_interface_t gw16012_interface;
 #endif
 
-#if BUILD_PRESTO == 1
+#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
        extern jtag_interface_t presto_interface;
 #endif
 
@@ -192,7 +192,7 @@ jtag_interface_t *jtag_interfaces[] = {
 #if BUILD_GW16012 == 1
        &gw16012_interface,
 #endif
-#if BUILD_PRESTO == 1
+#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
        &presto_interface,
 #endif
 #if BUILD_USBPROG == 1
index 95c59303b0d68fa936a1857a07f66369c0659408..084ae91799e91230d4392395579638b26c8a1739 100644 (file)
 #include <sys/time.h>
 #include <time.h>
 
-#include "ftd2xx.h"
+/* PRESTO access library includes */
+#if BUILD_PRESTO_FTD2XX == 1
+#include <ftd2xx.h>
+#elif BUILD_PRESTO_LIBFTDI == 1
+#include <ftdi.h>
+#endif
 
 
 int presto_jtag_speed(int speed);
@@ -67,7 +72,7 @@ jtag_interface_t presto_interface =
 int presto_bitq_out(int tms, int tdi, int tdo_req);
 int presto_bitq_flush(void);
 int presto_bitq_sleep(unsigned long us);
-int presto_bitq_reset(int rst, int en);
+int presto_bitq_reset(int trst, int srst);
 int presto_bitq_in_rdy(void);
 int presto_bitq_in(void);
 
@@ -89,25 +94,27 @@ bitq_interface_t presto_bitq =
 #define FT_DEVICE_SERNUM_LEN 64
 
 #define PRESTO_VID_PID 0x0403f1a0
-
-#define PRST_OK 0
-#define PRST_ERR 1
-#define PRST_TIMEOUT 2
+#define PRESTO_VID (0x0403)
+#define PRESTO_PID (0xf1a0)
 
 #define BUFFER_SIZE (64*62)
 
-
 typedef struct presto_s
 {
+#if BUILD_PRESTO_FTD2XX == 1
        FT_HANDLE handle;
        FT_STATUS status;
+#elif BUILD_PRESTO_LIBFTDI == 1
+       struct ftdi_context ftdic;
+       int retval;
+#endif
        
        char serial[FT_DEVICE_SERNUM_LEN];
 
-       BYTE buff_out[BUFFER_SIZE];
+       u8 buff_out[BUFFER_SIZE];
        int buff_out_pos;
 
-       BYTE buff_in[BUFFER_SIZE];
+       u8 buff_in[BUFFER_SIZE];
        int buff_in_exp; /* expected in buffer length */
        int buff_in_len; /* length of data received */
        int buff_in_pos;
@@ -124,15 +131,88 @@ typedef struct presto_s
 } presto_t;
 
 presto_t presto_state;
-presto_t *presto=&presto_state;
+presto_t *presto = &presto_state;
 
-BYTE presto_init_seq[] =
+u8 presto_init_seq[] =
 {
-       0x80,   0xA0,   0xA8,   0xB0,   0xC0,   0xE0
+       0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
 };
 
+int presto_write(u8 *buf, int size, u32* bytes_written)
+{
+#if BUILD_PRESTO_FTD2XX == 1
+       DWORD dw_bytes_written;
+       if ((presto->status = FT_Write(presto->handle, buf, size, &dw_bytes_written)) != FT_OK)
+       {
+               *bytes_written = dw_bytes_written;
+               ERROR("FT_Write returned: %lu", presto->status);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+       else
+       {
+               *bytes_written = dw_bytes_written;
+               return ERROR_OK;        
+       }
+#elif BUILD_PRESTO_LIBFTDI == 1
+       if ((presto->retval = ftdi_write_data(&presto->ftdic, buf, size)) < 0)
+       {
+               *bytes_written = 0;
+               ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto->ftdic));
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+       else
+       {
+               *bytes_written = retval;
+               return ERROR_OK;        
+       }
+#endif
+}
 
-int presto_open(char *req_serial)
+int presto_read(u8* buf, int size, u32* bytes_read)
+{
+#if BUILD_PRESTO_FTD2XX == 1
+       DWORD dw_bytes_read;
+       int timeout = 5;
+       *bytes_read = 0;
+
+       while ((*bytes_read < size) && timeout--)
+       {
+               if ((presto->status = FT_Read(presto->handle, buf + *bytes_read, size - 
+                       *bytes_read, &dw_bytes_read)) != FT_OK)         
+               {
+                       *bytes_read = 0; 
+                       ERROR("FT_Read returned: %lu", presto->status);
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
+               *bytes_read += dw_bytes_read; 
+       }
+#elif BUILD_PRESTO_LIBFTDI == 1
+       int timeout = 100;
+       *bytes_read = 0;
+       
+       while ((*bytes_read < size) && timeout--)
+       {
+               if ((presto->retval = ftdi_read_data(&presto->ftdic, buf + *bytes_read, size - *bytes_read)) < 0)
+               {
+                       *bytes_read = 0;
+                       ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto->ftdic));
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
+               *bytes_read += retval;
+       }
+#endif
+
+       if (*bytes_read < size)
+       {
+               ERROR("couldn't read the requested number of bytes from PRESTO (%i < %i)", *bytes_read, size);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+       
+       return ERROR_OK;
+}
+
+#if BUILD_PRESTO_FTD2XX == 1
+int presto_open_ftd2xx(char *req_serial)
 {
        int i;
        DWORD numdevs;
@@ -144,90 +224,204 @@ int presto_open(char *req_serial)
        unsigned long ftbytes;
 
        presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
+       
+#if IS_WIN32 == 0
+       /* Add non-standard Vid/Pid to the linux driver */
+       if ((presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID)) != FT_OK)
+       {
+               ERROR("couldn't add PRESTO VID/PID");
+               exit(-1);
+       }
+#endif
 
-       presto->buff_out_pos=0;
-       presto->buff_in_pos=0;
-       presto->buff_in_len=0;
-       presto->buff_in_exp=0;
-
-       presto->total_out=0;
-       presto->total_in=0;
-
-       presto->jtag_tms=0;
-       presto->jtag_tck=0;
-       presto->jtag_tdi_data=0;
-       presto->jtag_tdi_count=0;
-
-       if (FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY)!=FT_OK) return PRST_ERR;
-       for (i=0; i<numdevs; i++)
+       if ((presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY)) != FT_OK)
        {
-               if (FT_Open(i, &(presto->handle))!=FT_OK) continue;
-               if (FT_GetDeviceInfo(presto->handle,&device,&vidpid,presto->serial,devname,NULL)==FT_OK)
+               ERROR("FT_ListDevices failed: %i", (int)presto->status);
+               return ERROR_JTAG_INIT_FAILED;
+       }
+       
+       for (i = 0; i < numdevs; i++)
+       {
+               if (FT_Open(i, &(presto->handle)) != FT_OK)
                {
-                       if (vidpid==PRESTO_VID_PID && (req_serial==NULL || !strcmp(presto->serial,req_serial)))
+                       ERROR("FT_Open failed: %i", (int)presto->status);
+                       continue;
+               }
+                       
+               if (FT_GetDeviceInfo(presto->handle, &device, &vidpid,
+                               presto->serial, devname, NULL) == FT_OK)
+               {
+                       if (vidpid == PRESTO_VID_PID
+                                       && (req_serial == NULL || !strcmp(presto->serial, req_serial)))
                                break;
                }
+               
                FT_Close(presto->handle);
                presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
        }
 
-       if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE) return PRST_ERR;
-
-       if ((presto->status=FT_SetLatencyTimer(presto->handle,1))!=FT_OK) return PRST_ERR;
-       if ((presto->status=FT_SetTimeouts(presto->handle,100,0))!=FT_OK) return PRST_ERR;
-       if ((presto->status=FT_Purge(presto->handle, FT_PURGE_TX|FT_PURGE_RX))!=FT_OK) return PRST_ERR;
+       if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
+               return ERROR_JTAG_INIT_FAILED;
+       if ((presto->status = FT_SetLatencyTimer(presto->handle, 1)) != FT_OK)
+               return ERROR_JTAG_INIT_FAILED;
+       if ((presto->status = FT_SetTimeouts(presto->handle, 100, 0)) != FT_OK)
+               return ERROR_JTAG_INIT_FAILED;
+       if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
+               return ERROR_JTAG_INIT_FAILED;
 
-       presto_data=0xD0;
-       if ((presto->status=FT_Write(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
-       if ((presto->status=FT_Read(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
+       presto_data = 0xD0;
+       if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
+               return ERROR_JTAG_INIT_FAILED;
+       if ((presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
+               return ERROR_JTAG_INIT_FAILED;
 
        if (ftbytes!=1)
        {
-               if ((presto->status=FT_SetBitMode(presto->handle,0x80,1))!=FT_OK) return PRST_ERR;
-               if ((presto->status=FT_Purge(presto->handle, FT_PURGE_TX|FT_PURGE_RX))!=FT_OK) return PRST_ERR ;
-               if ((presto->status=FT_SetBaudRate(presto->handle,9600))!=FT_OK) return PRST_ERR;
-
-               presto_data=0;
-               for (i=0; i<4*62; i++)
-                       if ((presto->status=FT_Write(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
+               if ((presto->status = FT_SetBitMode(presto->handle, 0x80, 1)) != FT_OK)
+                       return ERROR_JTAG_INIT_FAILED;
+               if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
+                       return ERROR_JTAG_INIT_FAILED ;
+               if ((presto->status = FT_SetBaudRate(presto->handle, 9600)) != FT_OK)
+                       return ERROR_JTAG_INIT_FAILED;
+
+               presto_data = 0;
+               for (i = 0; i < 4 * 62; i++)
+                       if ((presto->status=FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
+                               return ERROR_JTAG_INIT_FAILED;
 
                usleep(100000);
 
-               if ((presto->status=FT_SetBitMode(presto->handle,0x00,0))!=FT_OK) return PRST_ERR;
-               if ((presto->status=FT_Purge(presto->handle, FT_PURGE_TX|FT_PURGE_RX))!=FT_OK) return PRST_ERR;
-
-               presto_data=0xD0;
-               if ((presto->status=FT_Write(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
-               if ((presto->status=FT_Read(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
-               if (ftbytes!=1) return PRST_ERR;
+               if ((presto->status = FT_SetBitMode(presto->handle, 0x00, 0)) != FT_OK)
+                       return ERROR_JTAG_INIT_FAILED;
+               if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
+                       return ERROR_JTAG_INIT_FAILED;
+
+               presto_data = 0xD0;
+               if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
+                       return ERROR_JTAG_INIT_FAILED;
+               if ((presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
+                       return ERROR_JTAG_INIT_FAILED;
+               if (ftbytes!=1)
+                       return ERROR_JTAG_INIT_FAILED;
        }
 
-       if ((presto->status=FT_SetTimeouts(presto->handle,0,0))!=FT_OK) return PRST_ERR;
+       if ((presto->status = FT_SetTimeouts(presto->handle, 0, 0)) != FT_OK)
+               return ERROR_JTAG_INIT_FAILED;
 
-       presto->status=FT_Write(presto->handle,&presto_init_seq,sizeof(presto_init_seq),&ftbytes);
-       if (presto->status!=FT_OK) return PRST_ERR;
-       if (ftbytes!=sizeof(presto_init_seq)) return PRST_TIMEOUT;
+       presto->status = FT_Write(presto->handle, &presto_init_seq, sizeof(presto_init_seq), &ftbytes);
+       if (presto->status != FT_OK)
+               return ERROR_JTAG_INIT_FAILED;
+       if (ftbytes != sizeof(presto_init_seq))
+               return ERROR_JTAG_INIT_FAILED;
 
-       return PRST_OK;
+       return ERROR_OK;
 }
 
+#elif BUILD_PRESTO_LIBFTDI == 1
+int presto_open_libftdi(char *req_serial)
+{
+       u8 presto_data;
+       u32 ftbytes;
+               
+       DEBUG("searching for presto JTAG interface using libftdi");
+
+       /* context, vendor id, product id */
+       if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0)
+       {
+               ERROR("unable to open presto: %s", presto->ftdic.error_str);
+               return ERROR_JTAG_INIT_FAILED;
+       }
+       
+       if (ftdi_usb_reset(&presto->ftdic) < 0)
+       {
+               ERROR("unable to reset presto device");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0)
+       {
+               ERROR("unable to set latency timer");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       if (ftdi_usb_purge_buffers(&presto->ftdic) < 0)
+       {
+               ERROR("unable to purge presto buffer");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+       
+       presto_data = 0xD0;
+       if ((presto->retval = presto_write(&presto_data, 1, &ftbytes)) != ERROR_OK)
+               return ERROR_JTAG_INIT_FAILED;
+       if ((presto->retval = presto_read(&presto_data, 1, &ftbytes)) != ERROR_OK)
+               return ERROR_JTAG_INIT_FAILED;
+       
+       return ERROR_OK;
+}
+#endif /* BUILD_PRESTO_LIBFTDI == 1 */
+
+int presto_open(char *req_serial)
+{
+       presto->buff_out_pos=0;
+       presto->buff_in_pos=0;
+       presto->buff_in_len=0;
+       presto->buff_in_exp=0;
+
+       presto->total_out=0;
+       presto->total_in=0;
+
+       presto->jtag_tms=0;
+       presto->jtag_tck=0;
+       presto->jtag_tdi_data=0;
+       presto->jtag_tdi_count=0;
+
+#if BUILD_PRESTO_FTD2XX == 1
+       return presto_open_ftd2xx(req_serial);
+#elif BUILD_PRESTO_LIBFTDI == 1
+       return presto_open_libftdi(req_serial);
+#endif
+}
 
 int presto_close(void)
 {
-       unsigned long ftbytes;
 
-       int result=PRST_OK;
+       int result = ERROR_OK;
 
-       if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE) return result;
+#if BUID_PRESTO_FTD2XX == 1
+       unsigned long ftbytes;
 
-       presto->status=FT_Write(presto->handle,&presto_init_seq,sizeof(presto_init_seq),&ftbytes);
-       if (presto->status!=FT_OK) result=PRST_ERR;
-       if (ftbytes!=sizeof(presto_init_seq)) result=PRST_TIMEOUT;
+       if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
+               return result;
 
-       if ((presto->status=FT_SetLatencyTimer(presto->handle,16))!=FT_OK) result=PRST_ERR;
+       presto->status = FT_Write(presto->handle, &presto_init_seq, sizeof(presto_init_seq), &ftbytes);
+       if (presto->status != FT_OK)
+               result = PRST_ERR;
+       if (ftbytes != sizeof(presto_init_seq))
+               result = PRST_TIMEOUT;
 
-       if ((presto->status=FT_Close(presto->handle))!=FT_OK) result=PRST_ERR;
-       else presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
+       if ((presto->status = FT_SetLatencyTimer(presto->handle, 16)) != FT_OK)
+               result = PRST_ERR;
+
+       if ((presto->status = FT_Close(presto->handle)) != FT_OK)
+               result = PRST_ERR;
+       else
+               presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
+       
+#elif BUILD_PRESTO_LIBFTDI == 1
+       
+       if ((presto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq))) < 0)
+       {
+               result = ERROR_JTAG_DEVICE_ERROR;
+       }
+       
+       if ((presto->retval = ftdi_set_latency_timer(&presto->ftdic, 16)) < 0)
+       {
+               result = ERROR_JTAG_DEVICE_ERROR;
+       }
+       
+       ftdi_deinit(&presto->ftdic);
+       
+#endif
 
        return result;
 }
@@ -235,77 +429,92 @@ int presto_close(void)
 
 int presto_flush(void)
 {
-       unsigned long ftbytes;
+       u32 ftbytes;
+
+       if (presto->buff_out_pos == 0)
+               return ERROR_OK;
 
-       if (presto->buff_out_pos==0) return PRST_OK;
-       if (presto->status!=FT_OK) return PRST_ERR;
+#if BUILD_PRESTO_FTD2XX == 1
+       if (presto->status != FT_OK)
+#elif BUILD_PRESTO_LIBFTDI == 1
+       if (presto->retval != ERROR_OK)
+#endif
+               return ERROR_JTAG_DEVICE_ERROR;
 
-       if ((presto->status=FT_Write(presto->handle, presto->buff_out, presto->buff_out_pos, &ftbytes))!=FT_OK)
+
+       if (presto_write(presto->buff_out, presto->buff_out_pos, &ftbytes) != ERROR_OK)
        {
-               presto->buff_out_pos=0;
-               return PRST_ERR;
+               presto->buff_out_pos = 0;
+               return ERROR_JTAG_DEVICE_ERROR;
        }
 
-       presto->total_out+=ftbytes;
+       presto->total_out += ftbytes;
 
-       if (presto->buff_out_pos!=ftbytes)
+       if (presto->buff_out_pos != ftbytes)
        {
-               presto->buff_out_pos=0;
-               return PRST_TIMEOUT;
+               presto->buff_out_pos = 0;
+               return ERROR_JTAG_DEVICE_ERROR;
        }
 
-       presto->buff_out_pos=0;
+       presto->buff_out_pos = 0;
 
-       if (presto->buff_in_exp==0) return PRST_OK;
+       if (presto->buff_in_exp == 0)
+               return ERROR_OK;
 
-       presto->buff_in_pos=0;
-       presto->buff_in_len=0;
+       presto->buff_in_pos = 0;
+       presto->buff_in_len = 0;
 
-       if ((presto->status=FT_Read(presto->handle, presto->buff_in, presto->buff_in_exp, &ftbytes))!=FT_OK)
+       if (presto_read(presto->buff_in, presto->buff_in_exp, &ftbytes) != ERROR_OK)
        {
-               presto->buff_in_exp=0;
-               return PRST_ERR;
+               presto->buff_in_exp = 0;
+               return ERROR_JTAG_DEVICE_ERROR;
        }
 
-       presto->total_in+=ftbytes;
+       presto->total_in += ftbytes;
 
-       if (ftbytes!=presto->buff_in_exp)
+       if (ftbytes != presto->buff_in_exp)
        {
-               presto->buff_in_exp=0;
-               return PRST_TIMEOUT;
+               presto->buff_in_exp = 0;
+               return ERROR_JTAG_DEVICE_ERROR;
        }
 
-       presto->buff_in_len=presto->buff_in_exp;
-       presto->buff_in_exp=0;
+       presto->buff_in_len = presto->buff_in_exp;
+       presto->buff_in_exp = 0;
 
-       return PRST_OK;
+       return ERROR_OK;
 }
 
 
 int presto_sendbyte(int data)
 {
-       if (data==EOF) return presto_flush();
+       if (data == EOF) return presto_flush();
 
        if (presto->buff_out_pos < BUFFER_SIZE)
        {
-               presto->buff_out[presto->buff_out_pos++]=(BYTE)data;
-               if (((data&0xC0)==0x40) || ((data&0xD0)==0xD0))
+               presto->buff_out[presto->buff_out_pos++] = (u8)data;
+               if (((data & 0xC0) == 0x40) || ((data & 0xD0)== 0xD0))
                        presto->buff_in_exp++;
        }
-       else return PRST_ERR;
+       else
+               return ERROR_JTAG_DEVICE_ERROR;
 
-       if (presto->buff_out_pos >= BUFFER_SIZE) return presto_flush();
-       return PRST_OK;
+       if (presto->buff_out_pos >= BUFFER_SIZE)
+               return presto_flush();
+       
+       return ERROR_OK;
 }
 
 
 int presto_getbyte(void)
 {
-       if (presto->buff_in_pos<presto->buff_in_len)
+       if (presto->buff_in_pos < presto->buff_in_len)
                return presto->buff_in[presto->buff_in_pos++];
 
-       if (presto->buff_in_exp==0) return -1;
-       if (presto_flush()!=PRST_OK) return -1;
+       if (presto->buff_in_exp == 0)
+               return -1;
+       
+       if (presto_flush() != ERROR_OK)
+               return -1;
 
        if (presto->buff_in_pos<presto->buff_in_len)
                return presto->buff_in[presto->buff_in_pos++];
@@ -321,46 +530,55 @@ int presto_bitq_out(int tms, int tdi, int tdo_req)
 {
        unsigned char cmdparam;
 
-       if (presto->jtag_tck==0)
+       if (presto->jtag_tck == 0)
        {
                presto_sendbyte(0xA4);
-               presto->jtag_tck=1;
+               presto->jtag_tck = 1;
        }
 
-       else if (!tdo_req && tms==presto->jtag_tms)
+       else if (!tdo_req && tms == presto->jtag_tms)
        {
-               if (presto->jtag_tdi_count==0) presto->jtag_tdi_data=(tdi!=0);
-               else presto->jtag_tdi_data|=(tdi!=0)<<presto->jtag_tdi_count;
-               if (++presto->jtag_tdi_count==4)
+               if (presto->jtag_tdi_count == 0)
+                       presto->jtag_tdi_data = (tdi != 0);
+               else
+                       presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;
+               
+               if (++presto->jtag_tdi_count == 4)
                {
-                       presto->jtag_tdi_data|=(presto->jtag_tdi_count-1)<<4;
+                       presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
                        presto_sendbyte(presto->jtag_tdi_data);
-                       presto->jtag_tdi_count=0;
+                       presto->jtag_tdi_count = 0;
                }
                return 0;
        }
 
        if (presto->jtag_tdi_count)
        {
-               presto->jtag_tdi_data|=(presto->jtag_tdi_count-1)<<4;
+               presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
                presto_sendbyte(presto->jtag_tdi_data);
-               presto->jtag_tdi_count=0;
+               presto->jtag_tdi_count = 0;
        }
 
-       if (tdi) cmdparam=0x0B;
-       else cmdparam=0x0A;
+       if (tdi)
+               cmdparam = 0x0B;
+       else
+               cmdparam = 0x0A;
 
-       presto_sendbyte(0xC0|cmdparam);
+       presto_sendbyte( 0xC0 | cmdparam);
 
-       if (tms!=presto->jtag_tms)
+       if (tms != presto->jtag_tms)
        {
-               if (tms) presto_sendbyte(0xEC);
-               else presto_sendbyte(0xE8);
-               presto->jtag_tms=tms;
+               if (tms)
+                       presto_sendbyte(0xEC);
+               else
+                       presto_sendbyte(0xE8);
+               presto->jtag_tms = tms;
        }
 
-       if (tdo_req) presto_sendbyte(0xD4|cmdparam);
-       else presto_sendbyte(0xC4|cmdparam);
+       if (tdo_req)
+               presto_sendbyte(0xD4 | cmdparam);
+       else
+               presto_sendbyte(0xC4|cmdparam);
 
        return 0;
 }
@@ -370,13 +588,13 @@ int presto_bitq_flush(void)
 {
        if (presto->jtag_tdi_count)
        {
-               presto->jtag_tdi_data|=(presto->jtag_tdi_count-1)<<4;
+               presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
                presto_sendbyte(presto->jtag_tdi_data);
-               presto->jtag_tdi_count=0;
+               presto->jtag_tdi_count = 0;
        }
 
        presto_sendbyte(0xCA);
-       presto->jtag_tck=0;
+       presto->jtag_tck = 0;
 
        presto_sendbyte(0xA0);
 
@@ -386,14 +604,16 @@ int presto_bitq_flush(void)
 
 int presto_bitq_in_rdy(void)
 {
-       if (presto->buff_in_pos>=presto->buff_in_len) return 0;
+       if (presto->buff_in_pos>=presto->buff_in_len)
+               return 0;
        return presto->buff_in_len-presto->buff_in_pos;
 }
 
 
 int presto_bitq_in(void)
 {
-       if (presto->buff_in_pos>=presto->buff_in_len) return -1;
+       if (presto->buff_in_pos>=presto->buff_in_len)
+               return -1;
        if (presto->buff_in[presto->buff_in_pos++]&0x08) return 1;
        return 0;
 }
@@ -403,15 +623,16 @@ int presto_bitq_sleep(unsigned long us)
 {
        long waits;
 
-       if (us>100000)
+       if (us > 100000)
        {
                presto_bitq_flush();
                jtag_sleep(us);
                return 0;
        }
 
-       waits=us/170+2;
-       while (waits--) presto_sendbyte(0x80);
+       waits = us / 170 + 2;
+       while (waits--)
+               presto_sendbyte(0x80);
 
        return 0;
 }
@@ -421,10 +642,12 @@ int presto_bitq_reset(int trst, int srst)
 {
        unsigned char cmd;
 
-       cmd=0xE8;
-       if (presto->jtag_tms) cmd|=0x04;
+       cmd = 0xE8;
+       if (presto->jtag_tms)
+               cmd |= 0x04;
 
-       if (trst || srst) cmd|=0x02;
+       if (trst || srst)
+               cmd |= 0x02;
 
        presto_sendbyte(cmd);
        return 0;
@@ -436,7 +659,7 @@ int presto_bitq_reset(int trst, int srst)
 
 int presto_jtag_speed(int speed)
 {
-       jtag_speed=speed;
+       jtag_speed = speed;
        return ERROR_OK;
 }
 
@@ -447,7 +670,8 @@ int presto_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, c
 {
        if (argc == 1)
        {
-               if (presto_serial) free(presto_serial);
+               if (presto_serial)
+                       free(presto_serial);
                presto_serial = strdup(args[0]);
        }
        else
@@ -469,16 +693,18 @@ int presto_jtag_register_commands(struct command_context_s *cmd_ctx)
 
 int presto_jtag_init(void)
 {
-       if (presto_open(presto_serial)!=0)
+       if (presto_open(presto_serial) != ERROR_OK)
        {
                presto_close();
-               if (presto_serial!=NULL) ERROR("Cannot open PRESTO, serial number %s", presto_serial);
-               else ERROR("Cannot open PRESTO");
+               if (presto_serial != NULL)
+                       ERROR("Cannot open PRESTO, serial number '%s'", presto_serial);
+               else
+                       ERROR("Cannot open PRESTO");
                return ERROR_JTAG_INIT_FAILED;
        }
-       INFO("PRESTO open, serial number %s", presto->serial);
+       INFO("PRESTO open, serial number '%s'", presto->serial);
        
-       bitq_interface=&presto_bitq;
+       bitq_interface = &presto_bitq;
        return ERROR_OK;
 }
 
@@ -492,7 +718,7 @@ int presto_jtag_quit(void)
        if (presto_serial)
        {
                free(presto_serial);
-               presto_serial=NULL;
+               presto_serial = NULL;
        }
 
        return ERROR_OK;
index 9c843707d8cc30f9430ed3d69c8ae518480312a7..f7261c779b0d33fd1041f1e5d6850b6b57d81957 100644 (file)
@@ -18,7 +18,7 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#define OPENOCD_VERSION "Open On-Chip Debugger (2007-08-10 22:30 CEST)"
+#define OPENOCD_VERSION "Open On-Chip Debugger (2007-08-14 11:45 CEST)"
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
index c85f387d5d051d39fdd5d871fdf05824fd2297a7..0c203f6b57b3df37c00c0c3eebe2982b49766858 100644 (file)
@@ -878,30 +878,37 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu
 
 int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data)
 {
+       image_section_t *section;
+       
        /* only image builder supports adding sections */
        if (image->type != IMAGE_BUILDER)
                return ERROR_INVALID_ARGUMENTS;
        
-       /* see if it's enough to extend an existing section */
-       if (((image->sections[image->num_sections - 1].base_address + image->sections[image->num_sections - 1].size) == base)
-               && (image->sections[image->num_sections - 1].flags == flags))
+       /* see if there's a previous section */
+       if (image->num_sections)
        {
-               u32 old_size = image->sections[image->num_sections - 1].size;
-               image->sections[image->num_sections - 1].size += size;
-               image->sections[image->num_sections - 1].private = realloc(image->sections[image->num_sections - 1].private, image->sections[image->num_sections - 1].size);
-               memcpy((u8*)image->sections[image->num_sections - 1].private + old_size, data, size);
+               section = &image->sections[image->num_sections - 1];
                
-               return ERROR_OK;
+               /* see if it's enough to extend the last section,
+                * adding data to previous sections or merging is not supported */
+               if (((section->base_address + section->size) == base) && (section->flags == flags))
+               {
+                       section->private = realloc(section->private, section->size + size);
+                       memcpy((u8*)section->private + section->size, data, size);
+                       section->size += size;
+                       return ERROR_OK;
+               }
        }
                
        /* allocate new section */
        image->num_sections++;
        image->sections = realloc(image->sections, sizeof(image_section_t) * image->num_sections);
-       image->sections[image->num_sections - 1].base_address = base;
-       image->sections[image->num_sections - 1].size = size;
-       image->sections[image->num_sections - 1].flags = flags;
-       image->sections[image->num_sections - 1].private = malloc(sizeof(u8) * size);
-       memcpy((u8*)image->sections[image->num_sections - 1].private, data, size);
+       section = &image->sections[image->num_sections - 1];
+       section->base_address = base;
+       section->size = size;
+       section->flags = flags;
+       section->private = malloc(sizeof(u8) * size);
+       memcpy((u8*)section->private, data, size);
        
        return ERROR_OK;
 }
index 905b10743589486bb40dddb3925e75a37cbbe701..de71b140fd4b4da9d1f5522f2878a211edc30e6a 100644 (file)
@@ -885,6 +885,7 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx,  NULL, "dump_binary", handle_dump_image_command, COMMAND_EXEC, "[DEPRECATED] dump_binary <file> <address> <size>");
        
        target_request_register_commands(cmd_ctx);
+       trace_register_commands(cmd_ctx);
        
        return ERROR_OK;
 }
@@ -1006,10 +1007,13 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a
                                /* initialize trace information */
                                (*last_target_p)->trace_info = malloc(sizeof(trace_t));
                                (*last_target_p)->trace_info->num_trace_points = 0;
+                               (*last_target_p)->trace_info->trace_points_size = 0;
                                (*last_target_p)->trace_info->trace_points = NULL;
                                (*last_target_p)->trace_info->trace_history_size = 0;
                                (*last_target_p)->trace_info->trace_history = NULL;
-                               
+                               (*last_target_p)->trace_info->trace_history_pos = 0;
+                               (*last_target_p)->trace_info->trace_history_overflowed = 0;
+                                                               
                                (*last_target_p)->type->target_command(cmd_ctx, cmd, args, argc, *last_target_p);
                                
                                found = 1;
index e84090205bc603f2bd6f290a1dbba381eee83f33..9dc58607986744b6c3e5d45553130ef68e1a48dd 100644 (file)
@@ -27,6 +27,7 @@
 #include "target_request.h"
 #include "binarybuffer.h"
 #include "command.h"
+#include "trace.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -54,35 +55,46 @@ int target_asciimsg(target_t *target, u32 length)
 
 int target_hexmsg(target_t *target, int size, u32 length)
 {
-       if (size == 1)
-       {
-               u8 *data = malloc(CEIL(length * sizeof(u8), 4) * 4);
-               
-               target->type->target_request_data(target, CEIL(length * sizeof(u8), 4), (u8*)data);
-               
-               free(data);
-       }
-       else if (size == 2)
-       {
-               u16 *data = malloc(CEIL(length * sizeof(u16), 4) * 4);
-               
-               target->type->target_request_data(target, CEIL(length * sizeof(u16), 4), (u8*)data);
+       u8 *data = malloc(CEIL(length * size, 4) * 4);
+       char line[128];
+       int line_len;
+       debug_msg_receiver_t *c = target->dbgmsg;
+       int i;
+       
+       DEBUG("size: %i, length: %i", size, length);
 
-               free(data);
-       }
-       else if (size == 4)
-       {
-               u32 *data = malloc(CEIL(length * sizeof(u32), 4) * 4);
-               
-               target->type->target_request_data(target, CEIL(length * sizeof(u32), 4), (u8*)data);
+       target->type->target_request_data(target, CEIL(length * size, 4), (u8*)data);
 
-               free(data);
-       }
-       else
+       line_len = 0;
+       for (i = 0; i < length; i++)
        {
-               ERROR("invalid debug message type");
+               switch (size)
+               {
+                       case 4:
+                               line_len += snprintf(line + line_len, 128 - line_len, "%8.8x ", le_to_h_u32(data + (4*i)));
+                               break;
+                       case 2:
+                               line_len += snprintf(line + line_len, 128 - line_len, "%4.4x ", le_to_h_u16(data + (2*i)));
+                               break;
+                       case 1:
+                               line_len += snprintf(line + line_len, 128 - line_len, "%2.2x ", data[i]);
+                               break;
+               }
+               
+               if ((i%8 == 7) || (i == length - 1))
+               {
+                       while (c)
+                       {
+                               command_print(c->cmd_ctx, "%s", line);
+                               c = c->next;
+                       }
+                       c = target->dbgmsg;
+                       line_len = 0;
+               }
        }
        
+       free(data);
+
        return ERROR_OK;
 }
 
@@ -96,7 +108,7 @@ int target_request(target_t *target, u32 request)
        switch (target_req_cmd)
        {
                case TARGET_REQ_TRACEMSG:
-                       DEBUG("tracepoint: %i", (request & 0xffffff00) >> 8);
+                       trace_point(target, (request & 0xffffff00) >> 8);
                        break;
                case TARGET_REQ_DEBUGMSG:
                        if (((request & 0xff00) >> 8) == 0)
@@ -196,6 +208,8 @@ int delete_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *targe
 
        do
        {
+               p = &target->dbgmsg;
+               c = *p;
                while (c)
                {
                        debug_msg_receiver_t *next = c->next;
index 3eec3d8335300244dd25d2e90fc3243623152a24..536e34a5f427cf0149d4b7e4cc57a6b82731fe0a 100644 (file)
 #include "log.h"
 #include "trace.h"
 #include "target.h"
+#include "command.h"
 
 #include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+int trace_point(target_t *target, int number)
+{
+       trace_t *trace = target->trace_info;
+
+       DEBUG("tracepoint: %i", number);
+       
+       if (number < trace->num_trace_points)
+               trace->trace_points[number].hit_counter++;
+
+       if (trace->trace_history_size)
+       {
+               trace->trace_history[trace->trace_history_pos++] = number;
+               if (trace->trace_history_pos == trace->trace_history_size)
+               {
+                       trace->trace_history_pos = 0;
+                       trace->trace_history_overflowed = 1;
+               }
+       }
+       
+       return ERROR_OK;
+}
+
+int handle_trace_point_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       target_t *target = get_current_target(cmd_ctx);
+       trace_t *trace = target->trace_info;
+       
+       if (argc == 0)
+       {
+               int i;
+               
+               for (i = 0; i < trace->num_trace_points; i++)
+               {
+                       command_print(cmd_ctx, "trace point 0x%8.8x (%"PRIi64" times hit)",
+                                       trace->trace_points[i].address,
+                                       trace->trace_points[i].hit_counter);
+               }
+
+               return ERROR_OK;
+       }
+       
+       if (!strcmp(args[0], "clear"))
+       {
+               if (trace->trace_points)
+                       free(trace->trace_points);
+               trace->num_trace_points = 0;
+               trace->trace_points_size = 0;
+               
+               return ERROR_OK;
+       }
+       
+       /* resize array if necessary */
+       if (!trace->trace_points || (trace->trace_points_size == trace->num_trace_points))
+       {
+               trace->trace_points = realloc(trace->trace_points, sizeof(trace_point_t) * (trace->trace_points_size + 32));
+               trace->trace_points_size += 32;
+       }
+       
+       trace->trace_points[trace->num_trace_points].address = strtoul(args[0], NULL, 0);
+       trace->trace_points[trace->num_trace_points].hit_counter = 0;
+       trace->num_trace_points++;
+       
+       return ERROR_OK;
+}
 
 int handle_trace_history_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
@@ -35,6 +103,15 @@ int handle_trace_history_command(struct command_context_s *cmd_ctx, char *cmd, c
        
        if (argc > 0)
        {
+               trace->trace_history_pos = 0;
+               trace->trace_history_overflowed = 0;
+
+               if (!strcmp(args[0], "clear"))
+               {
+                       /* clearing is implicit, we've just reset position anyway */
+                       return ERROR_OK;
+               }
+               
                if (trace->trace_history)
                        free(trace->trace_history);
                
@@ -46,24 +123,46 @@ int handle_trace_history_command(struct command_context_s *cmd_ctx, char *cmd, c
        else
        {
                int i;
+               int first = 0;
+               int last = trace->trace_history_pos;
+               
+               if (trace->trace_history_overflowed)
+               {
+                       first = trace->trace_history_pos;
+                       last = trace->trace_history_pos - 1;
+               }
                
-               for (i = 0; i < trace->trace_history_size; i++)
+               for (i = first; (i % trace->trace_history_size) != last; i++)
                {
-                       if (trace->trace_history[i] < trace->num_trace_points)
+                       if (trace->trace_history[i % trace->trace_history_size] < trace->num_trace_points)
                        {
                                u32 address;
-                               address = trace->trace_points[trace->trace_history[i]].address;
+                               address = trace->trace_points[trace->trace_history[i % trace->trace_history_size]].address;
                                command_print(cmd_ctx, "trace point %i: 0x%8.8x",
-                                       trace->trace_history[i],
+                                       trace->trace_history[i % trace->trace_history_size],
                                        address);
                        }
 
                        else
                        {
-                               command_print(cmd_ctx, "trace point %i: -not defined-", trace->trace_history[i]);
+                               command_print(cmd_ctx, "trace point %i: -not defined-", trace->trace_history[i % trace->trace_history_size]);
                        }
                }
        }
 
        return ERROR_OK;
 }
+
+int trace_register_commands(struct command_context_s *cmd_ctx)
+{
+       command_t *trace_cmd =
+               register_command(cmd_ctx, NULL, "trace", NULL, COMMAND_ANY, "trace commands");
+       
+       register_command(cmd_ctx, trace_cmd, "history", handle_trace_history_command,
+               COMMAND_EXEC, "display trace history, ['clear'] history or set [size]");
+
+       register_command(cmd_ctx, trace_cmd, "point", handle_trace_point_command,
+               COMMAND_EXEC, "display trace points, ['clear'] list of trace points, or add new tracepoint at [address]");
+
+       return ERROR_OK;
+}
index 7267cd38b92f7e6bfbb3c6167715072616a65a74..0279d51fa63ad4c29f91552102195f4a156f56a7 100644 (file)
@@ -31,9 +31,12 @@ typedef struct trace_point_s
 typedef struct trace_s
 {
        int num_trace_points;
+       int trace_points_size;
        trace_point_t *trace_points;
        int trace_history_size;
        u32 *trace_history;
+       int trace_history_pos;
+       int trace_history_overflowed;
 } trace_t;
 
 typedef enum trace_status
@@ -45,7 +48,9 @@ typedef enum trace_status
        TRACE_OVERFLOWED = 0x8,
 } trace_status_t;
 
-#define ERROR_TRACE_IMAGE_UNAVAILABLE  -(1500)
-#define ERROR_TRACE_INSTRUCTION_UNAVAILABLE    -(1500)
+extern int trace_point(struct target_s *target, int number);
+
+#define ERROR_TRACE_IMAGE_UNAVAILABLE          -(1500)
+#define ERROR_TRACE_INSTRUCTION_UNAVAILABLE    -(1501)
 
 #endif /* TRACE_H */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)