usb icon indicating copy to clipboard operation
usb copied to clipboard

xmega clock calibration issues

Open ahtn opened this issue 7 years ago • 0 comments

I found some issues with the 48MHz DFLL calibration with the xmega code. It was working some of the time but depending on the USB port used and the temperature, it would often fail to enumerate.

In the clock setup, the compare value for the DFLL is 0xB71B. The datasheet is a bit unclear here, but what it's supposed to be set to is the ratio between the target clock frequency and the DFLL reference frequency. That is for a target clock speed of 48MHz using the USB SOF at 1kHz (1kHz because SOF is every 1ms) the correct value to use is 48MHz / 1kHz = 48000 = 0xbb80.

Further I found that for best reliability, the DFLL should only be enabled once the xmega has started receiving SOF packets. My code looked like this:

ISR(USB_BUSEVENT_vect){
	if (USB.INTFLAGSACLR & USB_SOFIF_bm){
		USB.INTFLAGSACLR = USB_SOFIF_bm;

		// enable DFLL now
		DFLLRC32M.CTRL = DFLL_ENABLE_bm;

		// don't need SOF interrupts any more
		USB.INTCTRLA &= ~USB_SOFIE_bm;

	}else if (USB.INTFLAGSACLR & (USB_CRCIF_bm | USB_UNFIF_bm | USB_OVFIF_bm)){
		USB.INTFLAGSACLR = (USB_CRCIF_bm | USB_UNFIF_bm | USB_OVFIF_bm);
	}else if (USB.INTFLAGSACLR & USB_STALLIF_bm){
		USB.INTFLAGSACLR = USB_STALLIF_bm;
	}else{
		USB.INTFLAGSACLR = USB_SUSPENDIF_bm | USB_RESUMEIF_bm | USB_RSTIF_bm;

		if (USB.STATUS & USB_BUSRST_bm){
			USB.STATUS &= ~USB_BUSRST_bm;
			usb_reset();
			usb_cb_reset();

		}

		// disable the DFLL now that the USB device is suspended/reset
		DFLLRC32M.CTRL &= ~DFLL_ENABLE_bm;

		// re-enable the SOF interrupts so that the DFLL can be re-enabled
		// later.
		USB.INTCTRLA |= USB_SOFIE_bm;

		// re-load the factory calibration values for the RC oscillator
		NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
		DFLLRC32M.CALA = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSCA));
		DFLLRC32M.CALB = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC));
		NVM.CMD = NVM_CMD_NO_OPERATION_gc;
	}
}

EDIT: working code example can be found here:

ahtn avatar Jun 13 '17 06:06 ahtn