Hey guys, this is beyond my grasp so here's my problem and the workaround I've been using so far:
- XMEGA32A4U, using internal oscillator
- 32MHz internal RC tuned to 48MHz, system clock prescaled down to 12MHz
- USB interface enabled, full speed, ASF framework
- DFLL autocalibration using USBSOF
The target application is a USB keyboard controller. PCB layout, components and firmware are identical for every board. Everything is running fine - however, as I've just discovered, there's a small glitch that seems to stem from variations of the individual MCUs used.
The glitch is this: without DFLL USBSOF autocalibration, the keyboard controller's lock lights would randomly not get synchronized correctly, i.e. upon pressing, for example, the NL key on a second keyboard, the corresponding LED connected to my controller board would not light up or stay on sometimes. With DFLL USBSOF autocalibration this glitch didn't occur and the LEDs always got synchronized - until recently.
Interestingly, when sending data from the client to the host, there's never been a problem at all. The glitch in USB communication only occurs when receiving data from the host, s.a. a SET_REPORT request (which reports the operating system's lock light status to the client devices connected).
I discovered that when tweaking the DFLL COMP values, effectively synching to a higher clock speed than what it ought be, the problem will magically disappear - but only on two boards that I've been working on recently, on a third board the default DFLL COMP values work just fine:
ISR(USB_BUSEVENT_vect)
{
// USB bus event has occurred, so USB must be connected
if(usb_connected == false) usb_connected = true;
if (udd_is_start_of_frame_event())
{
udd_ack_start_of_frame_event();
udc_sof_notify();
if((DFLLRC32M.CTRL & DFLL_ENABLE_bm) == 0)
{
DFLLRC32M.COMP1 = 0x68;
DFLLRC32M.COMP2 = 0xBF;
OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc;
DFLLRC32M.CTRL |= DFLL_ENABLE_bm;
}
... // more code here
}
So, obviously, with the default value of 0xBB80 the USB clock is off as far as the two individual MCUs mentioned are concerned, otherwise there would be no glitches when receiving host data. So, can I conclude that with the a value of 0xBF68 (= 49MHz) the USB clock is now in fact closer to 48 MHz than before?
Another thing: if I don't enable DFLL autocalibration at all the mentioned glitches will also disappear - while with a third controller board that runs perfectly with the default DFLL settings, the glitches will only appear when DFLL autocalibration is disabled. So, I've got, technically speaking, identical boards running exactly the same firmware but there seem to be two different categories of MCU that behave completely differently on the same settings. What's going on here?