NXP Semiconductors logo
LPCXpresso Logo

Reply
 
Thread Tools
  #1  
Old 12-10-2010, 11:04 AM
pproc pproc is offline
Junior Member
 
Join Date: Nov 2010
Location: bangalore
Posts: 4
pproc is on a distinguished road
Default modifying usbhidrom with own system clock setup

I am using the built-in rom based usbhid driver on the lpc1343 for my application and so far functionality is OK. Now I would like to optimize the system clock for power consumption.

I commented out the call to the rom based init_clk_pins() function in the usbhidrom example. Replaced this with my code setting system clock to 12MHz and the usb clock using the usb pll to 48MHz, and initialized the usb io pins.

With just the modifications i have made so far, my application code runs fine, enumeration as HID works, the usb setreport function works, but the getreport function is never being called.

Since the usbhidrom driver uses CT32B1 internally - my question is, what do i need to do in my code to initialize CT32B1 given that I have modified the system clock to 12Mhz.

Is there anything else i am missing as well ?

regards hari

Last edited by pproc; 12-10-2010 at 11:11 AM. Reason: paragraph formatting disappeared ...
Reply With Quote
  #2  
Old 12-10-2010, 05:41 PM
NXP_USA NXP_USA is offline
Senior Member
 
Join Date: Nov 2009
Posts: 216
NXP_USA is on a distinguished road
Default

init_clk_pins() does not configure the timer, it only enables the USB phy, sets up the chip to run from the crystal at 48 MHz, and connects the USB pins (pin func selection).

There shouldn't be anything that the function does which would enable or disable the getreport callback given that setreport is working fine.

When you set up the USB clock did you use the external crystal oscillator? The internal RC oscillator cannot be used to drive USB.

-NXP
Reply With Quote
  #3  
Old 12-11-2010, 06:02 AM
pproc pproc is offline
Junior Member
 
Join Date: Nov 2010
Location: bangalore
Posts: 4
pproc is on a distinguished road
Default

Yes, I am using the 12MHz crystal on the evalboard. Sorry, should have shown the code in the first post itself !


Code:
int main(void) {
    clk_Config();
    comm_USBInit();
    ...
}


void clk_Config(void) {
    int i;
    LPC_SYSCON->PDRUNCFG     &= ~(1 << 5);   // Power-up System Osc
    LPC_SYSCON->SYSOSCCTRL    = 0;// not bypassed
    for (i = 0; i < 200; i++) Nop();
    LPC_SYSCON->SYSPLLCLKSEL  = 1;   // system oscillator
    LPC_SYSCON->SYSPLLCLKUEN  = 1;  // Update Clock Source
    LPC_SYSCON->SYSPLLCLKUEN  = 0;  // Toggle Update Register
    LPC_SYSCON->SYSPLLCLKUEN  = 1;
    while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01));  // Wait Until Updated
    LPC_SYSCON->SYSPLLCTRL    = 0; // (out = sys_osc*1)/1
    LPC_SYSCON->PDRUNCFG     &= ~(1 << 7);  // Power-up SYSPLL
    while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); // Wait Until PLL Locked
    LPC_SYSCON->MAINCLKSEL    = 3;     // sys_pll_out 3.5.15
    LPC_SYSCON->MAINCLKUEN    = 1;    // Update MCLK Clock Source
    LPC_SYSCON->MAINCLKUEN    = 0;    // Toggle Update Register
    LPC_SYSCON->MAINCLKUEN    = 1;
    while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); // Wait Until Updated
    SystemCoreClock = 12000000;
    }

void comm_USBInit(void) {
    volatile int n;

    HidDevInfo.idVendor = USB_VENDOR_ID;
    HidDevInfo.idProduct = USB_PRODUCT_ID;
    HidDevInfo.bcdDevice = USB_DEVICE;
    HidDevInfo.StrDescPtr = (uint32_t)&USB_StringDescriptor[0];
    HidDevInfo.InReportCount = GET_PKT_NBYTES;
    HidDevInfo.OutReportCount = SET_PKT_NBYTES;
    HidDevInfo.SampleInterval = GET_PKT_INTERVAL_MS;
    HidDevInfo.InReport = GetInReport;
    HidDevInfo.OutReport = SetOutReport;

    DeviceInfo.DevType = USB_DEVICE_CLASS_HUMAN_INTERFACE;
    DeviceInfo.DevDetailPtr = (uint32_t)&HidDevInfo;

    // Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver)
    LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);
    // Setup USB clock
    LPC_SYSCON->PDRUNCFG     &= ~(1 << 10);  // usb phy powered
    LPC_SYSCON->PDRUNCFG     &= ~(1 <<  8);  // usb pll powered

    LPC_SYSCON->USBPLLCLKSEL  = 1; // system oscillator
    LPC_SYSCON->USBPLLCLKUEN  = 1; // Update pll clock Source
    LPC_SYSCON->USBPLLCLKUEN  = 0; // toggle
    LPC_SYSCON->USBPLLCLKUEN  = 1;
    while (!(LPC_SYSCON->USBPLLCLKUEN & 0x01));     // Wait Until Updated

    LPC_SYSCON->USBPLLCTRL    = 3; // (sys_osc * 4)/ 1      3.5.5
    while (!(LPC_SYSCON->USBPLLSTAT   & 1));  // Wait Until PLL Locked
    LPC_SYSCON->USBCLKSEL     = 0;       // Select USB PLL out 3.5.23

    // Set USB pin functions
    LPC_IOCON->PIO0_1 &= ~0x07;
    LPC_IOCON->PIO0_1 |= 0x03;   // usb ftoggle

    LPC_IOCON->PIO0_3 &= ~0x1F;
    LPC_IOCON->PIO0_3 |= 0x01;   // usb vbus, no pullup/dn

    LPC_IOCON->PIO0_6 &= ~0x07;
    LPC_IOCON->PIO0_6 |= 0x01;   // usb soft connect

    gGetPktCntr = 0;
    gSetPktCntr = 0;

    // clock PLL and pin init function in rom
    // unused 
    //(*rom)->pUSBD->init_clk_pins();

    // insert a delay between clk init and usb init
    for (n = 0; n < 75; n++) {}
    (*rom)->pUSBD->init(&DeviceInfo);
    (*rom)->pUSBD->connect(TRUE);
    }
Is there any issue with setting the system clock independently? What is CT32B1 used for ? I looked for the usbhidrom source code but haven't found it - is that public ?

Any info would be appreciated - thanks !
Reply With Quote
  #4  
Old 12-14-2010, 09:18 AM
pproc pproc is offline
Junior Member
 
Join Date: Nov 2010
Location: bangalore
Posts: 4
pproc is on a distinguished road
Default

Checking the registers immediately after the call to
(*rom)->pUSBD->init_clk_pins();

I find that

USBPLLCLKSEL = 1 (select system oscillator : 12MHz crystal - OK)
USBPLLCTRL = 3 (output = 12*4/1 = 48MHz - OK)

but the USBCLKSEL register is set to 1, which selects the main clock for USB instead of the USB PLL output !!

Why ?!
Reply With Quote
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



All times are GMT +2. The time now is 10:15 AM.