Hello all,
I'm trying to get familiar with USBOTG module in Kinetis K60D512 MCU and I'm encountering some issues I'm not sure about.
First I don't understand why there's an USB interrupt signalizing set USBRST right after I enable only this interrupt source before pulling up D+ to signalize attached device.
The code I use is the following:
///******* CLOCK configuration *****************
// Configure USB to be clocked from PLL0
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK |SIM_SOPT2_USBSRC_MASK;
// Configure USB divider to be 2 (SYSCLOCK = 96MHz)
// USBclk = PLLclk × [ (USBFRAC+1) / (USBDIV+1) ]
SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(1);
// Enable USB-OTG IP clocking
SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
///********* USB configuration **********
// Enable interrupts
NVIC_EnableIRQ(USB0_IRQn);
// Configure enable USB regulator for device
SIM->SOPT1 |= SIM_SOPT1_USBREGEN_MASK;
// enable USB module
USB0->CTL |= USB_CTL_USBENSOFEN_MASK;
// Module reset
USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
// set BDT address
USB0->BDTPAGE1 = (uint8_t) ((uint32_t)&bdt >> 8);
USB0->BDTPAGE2 = (uint8_t) ((uint32_t)&bdt >> 16);
USB0->BDTPAGE3 = (uint8_t) ((uint32_t)&bdt >> 24);
// enable control of pullups
USB0->OTGCTL |= USB_OTGCTL_OTGEN_MASK;
// enable weak pull-downs and turn on transceiver
USB0->USBCTRL |= USB_USBCTRL_PDE_MASK;
USB0->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
// clear all USB ISR flags
USB0->ISTAT = 0xFF;
// enable USB RESET interrupt
USB0->INTEN |= USB_INTEN_USBRSTEN_MASK;
/// !!!! This chunk is executed from an interrupt handler for a button:
// signalize attached device
USB0->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
USB0->OTGCTL |= USB_OTGCTL_DPHIGH_MASK;
Right after line USB0->INTEN |= USB_INTEN_USBRSTEN_MASK there is an interrupt on USB0_IRQ signalizing USBRST event even though the pullup od D+ is off (I could check in OBSERVE reg). But when I press the button and enter its interrupt handler then the regular USBRST event occurs because Windows signalizes new USB device (of course unsuccessfully installed). So is there any reason for this behavior? Getting USBRST interrupt event right after enabling interrupts? I also tried to change the configuration of USB module commenting out and changing some of the previous register configurations but the result is always the same.
Is there any documentation on the USB controller used in this kinetis I'm using? The reference manual isn't very comprehensive and I think some things would really deserve more information. USB Stack examples really doesn't cover this too.
Thanks a lot for any help.
Buchta
1. After enabling the USB regulator it is usual to disable its standby mode (remove UVSWE bit)
2. When commanding the USB controller reset it is usual to wait for the reset to complete with
while (USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK) { | // wait for the reset to complete | |
} |
3. Before enabling the D+ pull up it is recommended to set 0x40 to USB0->USBTRC0. This is an undocumented bit but it is set in most code examples and ensures correct pull-up operation (for some reason).
4. When both bus lines are low for 2.5us it is detected as a USB reset. Therefore I think you should only enable the RST interrupt once you have actually pulled up the D+ line (for FS mode) and you will need to clear the pending interupt before as well.
Regards
Mark