How to use dfu-programmer?

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I want to try out dfu-programmer.  I downloaded the Windows program from here:  http://sourceforge.net/projects/dfu-programmer/files/dfu-programmer/0.7.0/

 

However I can't get it to work.  It looks like I'm using the right command line stuff, but it says "no device present". 

The command line format I am using is similar to this post:  https://www.avrfreaks.net/projects/atmel-dfu-programmer-win32?skey=dfu-programmer

 

Avrdude works fine.  It has no trouble finding the device.

 

Here is what I get with dfu-programmer:

C:\Downloads\dfu-programmer-win-0.7.2>.\dfu-programmer ATxmega128A4U dump
dfu-programmer: no device present.

C:\Downloads\dfu-programmer-win-0.7.2>

I tried lower case and that doesn't work either.

 

My device manager shows this:

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well it's giving that error here:

    device = dfu_device_init( args.vendor_id, args.chip_id,
                              args.bus_id, args.device_address,
                              &dfu_device,
                              args.initial_abort,
                              args.honor_interfaceclass );

    if( NULL == device ) {
        fprintf( stderr, "%s: no device present.\n", progname );
        retval = 1;
        goto error;
    }

So it's a pretty fair bet dfu_device_init() is returning NULL. Looking at that function:

struct usb_device *dfu_device_init( const uint32_t vendor,
                                    const uint32_t product,
                                    const uint32_t bus_number,
                                    const uint32_t device_address,
                                    dfu_device_t *dfu_device,
                                    const dfu_bool initial_abort,
                                    const dfu_bool honor_interfaceclass ) {
    struct usb_bus *usb_bus;
    struct usb_device *device;
    int32_t retries = 4;

    TRACE( "%s( %u, %u, %p, %s, %s )\n", __FUNCTION__, vendor, product,
           dfu_device, ((true == initial_abort) ? "true" : "false"),
           ((true == honor_interfaceclass) ? "true" : "false") );

retry:
    if( 0 < retries ) {
        usb_find_busses();
        usb_find_devices();

        /* Walk the tree and find our device. */
        for( usb_bus = usb_get_busses(); NULL != usb_bus; usb_bus = usb_bus->next ) {
            for( device = usb_bus->devices; NULL != device; device = device->next) {
                if(    (vendor  == device->descriptor.idVendor)
                    && (product == device->descriptor.idProduct)
                    && ((bus_number == 0)
                        || (device->devnum == device_address
                            && (usb_bus->location >> 24) == bus_number)))
                {
                    int32_t tmp;
                    DEBUG( "found device at USB:%d,%d\n", device->devnum, (usb_bus->location >> 24) );
                    /* We found a device that looks like it matches...
                     * let's try to find the DFU interface, open the device
                     * and claim it. */
                    tmp = dfu_find_interface( device, honor_interfaceclass );
                    if( 0 <= tmp ) {
                        /* The interface is valid. */
                        dfu_device->interface = tmp;
                        dfu_device->handle = usb_open( device );
                        if( NULL != dfu_device->handle ) {
                            if( 0 == usb_set_configuration(dfu_device->handle, 1) ) {
                                if( 0 == usb_claim_interface(dfu_device->handle, dfu_device->interface) ) {
                                    switch( dfu_make_idle(dfu_device, initial_abort) )
                                    {
                                        case 0:
                                            return device;
                                        case 1:
                                            retries--;
                                            goto retry;
                                    }

                                    DEBUG( "Failed to put the device in dfuIDLE mode.\n" );
                                    usb_release_interface( dfu_device->handle, dfu_device->interface );
                                    usb_close( dfu_device->handle );
                                    retries = 4;
                                } else {
                                    DEBUG( "Failed to claim the DFU interface.\n" );
                                    usb_close( dfu_device->handle );
                                }
                            } else {
                                DEBUG( "Failed to set configuration.\n");

                                usb_close( dfu_device->handle );
                            }
                        } else {
                            DEBUG( "Failed to open device.\n" );
                        }
                    } else {
                        DEBUG( "Failed to find the DFU interface.\n" );
                    }
                }
            }
        }
    }

    dfu_device->handle = NULL;
    dfu_device->interface = 0;

    return NULL;
}

It seems it would be useful to get the DEBUG() output. That is:

#define DEBUG(...)  dfu_debug( __FILE__, __FUNCTION__, __LINE__, \
                               DFU_DEBUG_THRESHOLD, __VA_ARGS__ )

and that function is:

void dfu_debug( const char *file, const char *function, const int line,
                const int level, const char *format, ... )
{
    if( level < debug ) {
        va_list va_arg;

        va_start( va_arg, format );
        fprintf( stderr, "%s:%d: ", file, line );
        vfprintf( stderr, format, va_arg );
        va_end( va_arg );
    }
}

So it seems pretty important that "debug" is a high enough value from amongst:

#define DFU_DEBUG_THRESHOLD         100
#define DFU_TRACE_THRESHOLD         200
#define DFU_MESSAGE_DEBUG_THRESHOLD 300

It's an int in main.c. It is handle by parse_arguments():

    /* Find '--debug' if it is here */
    for( i = 0; i < argc; i++ ) {
        if( 0 == strncmp("--debug", argv[i], 7) ) {

            if( 0 == strncmp("--debug=", argv[i], 8) ) {
                if( 1 != sscanf(argv[i], "--debug=%i", &debug) )
                    return -2;
            } else {
                if( (i+1) >= argc )
                    return -3;

                if( 1 != sscanf(argv[i+1], "%i", &debug) )
                    return -4;

                *argv[i+1] = '\0';
            }
            *argv[i] = '\0';
            break;
        }
    }

and the usage() confirms:

    fprintf( stderr, "global-options:\n"
                     "        --quiet\n"
                     "        --debug level    (level is an integer specifying level of detail)\n"
                     "        Global options can be used with any command and must come\n"
                     "        after the command and before any file or data value\n" );

So I think you want to add "--debug 100" to your command.

 

More generally note this:

static void basic_help()
{
    fprintf( stderr, PACKAGE_STRING "\n");
    fprintf( stderr, PACKAGE_URL "\n" );
    fprintf( stderr, "Type 'dfu-programmer --help'    for a list of commands\n" );
    fprintf( stderr, "     'dfu-programmer --targets' to list supported target devices\n" );
}

So just invoking it with --help is probably a good place to start.

 

(BTW why would the help tell you to use "--debug level" without telling you expected values of level? If I had been guessing I would have guessed 0,1,2,3 or something like that for "none", "info", "warn", "debug" perhaps - certainly not 100, 200, 300)

Last Edited: Tue. Mar 10, 2015 - 05:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks.  Using --debug 300 showed me something.  It seems that part of the initialization is to issue an abort command and see if I jump through the right hoops.  I didn't bother, but I'll try to get that working.   Avrdude didn't do that stuff.