AnsweredAssumed Answered

USB CDC Device on a K22FN1M0VLH12 - Device Cannot Start

Question asked by weblar on May 29, 2014
Latest reply on May 30, 2014 by weblar

Hi,

 

I've taken the K21 USB CDC example from the Freescale USB stack 4.11 and I've customized it to fit my K22 (not much needed changing to be honest).

 

When the application started, I was prompted to install the drive which Freescale kindly supplied with the aforementioned example code.

 

Unfortunately, I now always get a "device cannot start" error in device manager against the "Virtual Com Port" device and I can't for the life of me figure out what's going on. The USB_ISR interrupt seems to trigger correctly - my only thought would be as to whether I have correctly configured the clocking for the USB peripheral. I have an 8MHz crystal as the source with the device running at 120MHz, the following code is how I've configured the USB peripheral...

 

void usb_init(void) {

 

  // 2 / 5 * 120MHz = 48MHz

  SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(4) | SIM_CLKDIV2_USBFRAC_MASK;

 

  // Clock the USB from the PLL

  SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK;

 

  // Enable USB OTG module clock

  SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;

 

  USB0->USBTRC0 = 0x40;

 

  // Allow the USBREGEN bit in SOPT1 to be changed

  //SIM->SOPT1CFG |= SIM_SOPT1CFG_URWE_MASK;

 

  // Enable the USB regulator

  SIM->SOPT1 |= SIM_SOPT1_USBREGEN_MASK;

 

  // Clear any pending USB interrupts

  nvic_clear_irq(INT_USB0);

  // Enable the USB interrupt

  nvic_enable_irq(INT_USB0);

 

}

 

For reference, here is my mcg init code...

 

void mcg_init(void) {


  // Select the internal load capacitors for a capacitance of about 18pF

  OSC0->CR = (uint8_t)(OSC_CR_SC2P_MASK | OSC_CR_SC16P_MASK);

 

  // Enable the 8MHz crystal

  MCG->C2 = (uint8_t)(MCG_C2_EREFS0_MASK | MCG_C2_RANGE0(2));

 

  // Select the external oscillator and set the FLL reference divider

  MCG->C1 = (uint8_t)(MCG_C1_CLKS(2) | MCG_C1_FRDIV(3));

 

  // Wait for the oscillator to initialize

  while (!(MCG->S & MCG_S_OSCINIT0_MASK)) { }

 

  // Wait for the reference clock to switch to the external reference

  while (MCG->S & MCG_S_IREFST_MASK) { }

 

  // Wait for MCGOUTCLK to switch over to the external reference clock

  while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) { }

 

  // Divide by 2 for a PLL0 frequency of 4MHz

  MCG->C5 = (uint8_t)(MCG_C5_PRDIV0(1));

 

  // PLL0 - Multiply by 30 to give 120MHz

  MCG->C6 = (uint8_t)(MCG_C6_CME0_MASK | MCG_C6_PLLS_MASK | MCG_C6_VDIV0(6));

 

  // Wait for the PLLST bit to be set, when PLLCS has obtained a lock

  while (!(MCG->S & MCG_S_PLLST_MASK)) { }


  // Wait for PLL0 to lock

  while (!(MCG->S & MCG_S_LOCK0_MASK)) { }


  // Set the clocks to the following:

  // CORE_CLK = 120MHz (0 = div 1)

  // BUS_CLK = 60MHz (1 = div 2)

  // FLEXBUS_CLK = 40MHz (3 = div 4)

  // FLASH_CLK = 20MHz (5 = div 6)

  SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV3(3) | SIM_CLKDIV1_OUTDIV4(5);


  //MCG_C1 &= ~MCG_C1_CLKS_MASK;

  MCG->C1 = (uint8_t)(MCG_C1_CLKS(0) | MCG_C1_FRDIV(3));


  while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) { }

 

  MPU->CESR = 0x00;

 

}

 

As far as I'm aware, this is all correct as per the K21 example - apart from my device running up at 120MHz.

 

I'd be grateful if anyone could provide any hints or tips as to what may be the cause.

 

Thanks in advance,

Kevin

Outcomes