DFU bootloader not working

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

I created a bootloader with DFU functionality, and I'm having a hard time getting the USB transfer to work correctly.

The symptoms are as follows: either my device is consistently identified by the OS, but transfer is extremely unreliable (protocol errors everywhere), or my device is almost never identified by the OS, but if it is identified by the OS, then transfer works without any problems.

 

I'm working on ATXMEGA256A3U, and the ASF version I'm working with is 3.32.0. The development environment is Windows 10 on Atmel Studio 7.

 

My conf files are as follows:

conf_clock.h

#ifndef CONF_CLOCK_H_INCLUDED
#define CONF_CLOCK_H_INCLUDED

//sysclk sourced from the 2MHz internal oscilator, upscaled to 32MHz by a PLL
#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLL
#define CONFIG_PLL0_SOURCE          PLL_SRC_RC2MHZ
#define CONFIG_PLL0_MUL             16
#define CONFIG_PLL0_DIV             1

//Do not apply prescaler on sysclk output. Thus, all peripherals, RAM, NVM, and
//CPU are clocked using unmodified sysclk
#define CONFIG_SYSCLK_PSADIV          SYSCLK_PSADIV_1
#define CONFIG_SYSCLK_PSBCDIV         SYSCLK_PSBCDIV_1_1

/* DFLL autocalibration */
#define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC  OSC_ID_RC32KHZ

/* The following configures the USB controller clock
 * source to use the internal (nominally) 32MHz RC oscillator, up-calibrated to
 * run at 48MHz via the periodic 1ms USB Start Of Frame packets sent by the host.
 */
#define CONFIG_USBCLK_SOURCE                USBCLK_SRC_RCOSC
#define CONFIG_OSC_RC32_CAL                 48000000UL
#define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF

/* RTC uses the internal 32.768KHz oscillator, divided by 32 */
#define CONFIG_RTC_SOURCE     SYSCLK_RTCSRC_RCOSC

#endif /* CONF_CLOCK_H_INCLUDED */

conf_usb.h

#ifndef _CONF_USB_H_
#define _CONF_USB_H_

#include "compiler.h"

/**
 * USB Device Configuration
 * @{
 */

//! Device definition (mandatory)
#define  USB_DEVICE_VENDOR_ID             USB_VID_ATMEL
//TODO: see comment in this define
#define  USB_DEVICE_PRODUCT_ID            USB_PID_ATMEL_DFU_ATXMEGA256A3U
#define  USB_DEVICE_MAJOR_VERSION         1
#define  USB_DEVICE_MINOR_VERSION         0
#define  USB_DEVICE_POWER                 100 // Consumption on Vbus line (mA)
#define  USB_DEVICE_ATTR                  \
 (USB_CONFIG_ATTR_SELF_POWERED)
// (USB_CONFIG_ATTR_BUS_POWERED)
// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)

//! USB Device string definitions (Optional)
#define  USB_DEVICE_MANUFACTURE_NAME      "Manufacturer"
#define  USB_DEVICE_PRODUCT_NAME          "Product"
#define  USB_DEVICE_SERIAL_NAME           "12...EF"

/**
 * Device speeds support
 * Only Full speed is authorized on DFU ATMEL
 * Because FLIP supports only full speed
 * Also:
 * - low speed is too slow (endpoint 8 Bytes)
 * - high speed does not increase flash program speed
 * - high speed is not supported on custom board with bad USB layout
 * @{
 */
// No speed change possible
//@}

/**
 * USB Device Callbacks definitions (Optional)
 * @{
 */
// #define  UDC_VBUS_EVENT(b_vbus_high)      user_callback_vbus_action(b_vbus_high)
// extern void user_callback_vbus_action(bool b_vbus_high);
// #define  UDC_SOF_EVENT()                  user_callback_sof_action()
// extern void user_callback_sof_action(void);
// #define  UDC_SUSPEND_EVENT()              user_callback_suspend_action()
// extern void user_callback_suspend_action(void);
// #define  UDC_RESUME_EVENT()               user_callback_resume_action()
// extern void user_callback_resume_action(void);
//! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature
// #define  UDC_REMOTEWAKEUP_ENABLE()        user_callback_remotewakeup_enable()
// extern void user_callback_remotewakeup_enable(void);
// #define  UDC_REMOTEWAKEUP_DISABLE()       user_callback_remotewakeup_disable()
// extern void user_callback_remotewakeup_disable(void);
//! When a extra string descriptor must be supported
//! other than manufacturer, product and serial string
// #define  UDC_GET_EXTRA_STRING()
//@}

//@}


/**
 * USB Interface Configuration
 * @{
 */
/**
 * Configuration of DFU interface
 * @{
 */
//! Interface callback definition
#define  UDI_DFU_ENABLE_EXT()             true
#define  UDI_DFU_DISABLE_EXT()

//! FLIP protocol version to use
#define  FLIP_PROTOCOL_VERSION   FLIP_PROTOCOL_VERSION_2
// Split erase is available since batchisp 1.2.5 to avoid USB protocol 2 error
//TODO: this was originally uncommented. Do we need this?
//#define  UDI_DFU_ATMEL_PROTOCOL_2_SPLIT_ERASE_CHIP
// Reduce the RAM used (1KB instead of 2KB), but the CODE increase of 80B
//#define  UDI_DFU_SMALL_RAM
//@}
//@}


/**
 * USB Device Driver Configuration
 * @{
 */
//#define UDD_NO_SLEEP_MGR
//@}

//! The includes of classes and other headers must be done at the end of this file to avoid compile error
#include "udi_dfu_atmel_conf.h"

#endif // _CONF_USB_H_

main.c

int main (void)
{
 sysclk_init();
 osc_disable(OSC_ID_RC32KHZ);
 board_init();
 pmic_init();
 pmic_set_vector_location(PMIC_VEC_BOOT);
 cpu_irq_enable();

 if (true || force_boot_to_bootloader()) { // Coming from application
     isp_init();
     udc_start();
     while (true)
         wdt_reset();
 } else {
     CCP = CCP_IOREG_gc;  // unlock IVSEL
     PMIC.CTRL = 0;   // disable interrupts, set vector table to app section
     EIND = 0;    // indirect jumps go to app section
     RAMPZ = 0;    // LPM uses lower 64k of flash
     application_vector();
 }
}

If I comment out #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF​, I get the consistent identification I described above, but with screwed up transfers. If I leave it, and add osc_disable(OSC_ID_RC32KHZ);​ in the init section of main(), then I get the other symptom, where transfers work great, but the device is almost never identified by the OS. I've seen many people having problems with USB functionality on XMEGA, but none quite like what I'm experiencing. Can you see something I might be doing wrong?

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

 

 if (true || force_boot_to_bootloader())

 

When will the above condition (true || <anything>) be false?

 

EDIT: also, you set the RC2M AUTOCAL to RC32K, then you disable RC32K.

Greg Muth

Portland, OR, US

Atmel Studio 7.0 on Windows 10

Xplained/Pro/Mini Boards mostly

 

 

Last Edited: Sun. Sep 17, 2017 - 03:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Greg_Muth wrote:

 

 if (true || force_boot_to_bootloader())

 

When will the above condition (true || <anything>) be false?

 

EDIT: also, you set the RC2M AUTOCAL to RC32K, then you disable RC32K.

 

if (true) is debug code so that I could focus on that particular brunch. Same thing with disabling the RC32K. It was a suggestion I found online, and decided to see if it has any effect. I since determined that it doesn't make a difference, only commenting out the calibration for the USB code seem to affect the symptoms. With the calibration on, I rarely get to see the device recognized, but when it does, transfer works flawlessly.

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

Have you tried using an external crystal? We found the oscillator to be a little unreliable, especially at high speeds.

 

With the USB interface, are you using CDC or HID or something else?

Electronic System Design
http://www.esdn.com.au

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

Hefty wrote:

Have you tried using an external crystal? We found the oscillator to be a little unreliable, especially at high speeds.

 

With the USB interface, are you using CDC or HID or something else?

 

I am going to try an external crystal soon.

The USB interface I'm using is CDC. Which one would you recommend?

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

We found the internal RC oscillator to be a little unstable as well. I'd recommend HID, simply because it doesn't need drivers like CDC does. For uploading firmware it's more than fast enough.