You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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;
}
}
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 is48MHz / 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:
EDIT: working code example can be found here:
The text was updated successfully, but these errors were encountered: