打印
[资料分享与下载]

[经验分享]鼠标HID例程简析(上)

[复制链接]
2942|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
HID, USB, SIM, ST, TE
本帖最后由 FSL_TICS_Jeremy 于 2014-9-17 11:52 编辑

鼠标HID例程简析
   大家好,此文内容紧跟《FSL USB Stack 简介》一文,如果网友们先前没有浏览过《FSLUSB Stack 简介》,建议先下载浏览,然后再浏览本篇内容。本篇是以飞思卡尔的USB协议栈Freescale USB Stack v4.1.1中的鼠标HID例程为例,介绍USB Stack层式架构中的USB Application、HID Class Drivers 和 USB Drivers是如何各司其职,相互配合确保例程,本例程路径:<dir_stall>\USBFreescale USBStack v4.1.1\ Source\Device\app\hid\cw10\kinetis_l2k
1.   USBStack文件介绍
    图1为在CW10.6中打开的kinetis_l2k例程, 从中可看出,在USB Stack层式架构中,USB Application、HID ClassDrivers 和 USB Drivers都有属于本层的文件,表一则对各层的文件进行了归纳。


1 USB Stack 文件
表一






1.   鼠标HID例程代码
                主程序
*****************************************************************************
* This function initializes the system, enables the interrupts and calls the
* application
*****************************************************************************/
#ifdef __GNUC__
int main(void)
#else
void main(void)
#endif
{
        /* Initialize the system */
    SYS_Init(); //时钟配置:PEE模式,CORE_CLOCK、SYSTEM_CLOCK、BUS_CLOCK、FLASH_CLOCK为48MHz

#ifdef SERIAL_DEBUG
    sci_init();
#endif
#ifndef _SERIAL_AGENT_
    /* Initialize USB module */
#if HIGH_SPEED_DEVICE
    USB_Init(ULPI);
#else
    USB_Init(MAX3353);//USB模块初始化
#endif
#else
    SIM_SOPT2  |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK);
#endif
    /* Initialize GPIO pins */
    GPIO_Init(); //按键引脚初始化:PTA4、PTC3

#if MAX_TIMER_OBJECTS
    (void)TimerQInitialize(0);
#endif
   
    /* Initialize the USB Test Application */
    TestApp_Init();//鼠标HID应用运行开始,内含USB_Class_HID_Init()函数

    while(TRUE)
    {
            Watchdog_Reset();
            /* Call the application task */
            TestApp_Task();//应用任务函数
    }

#ifdef __GNUC__
    return 0;
#endif
}



      pll_init() SYS_Init()函数中包含pll_init()函数用于配置PEE时钟模式和各个时钟源的频率。
static int pll_init()
{
#elif (defined MCU_MKL25Z4)   
    /* Update system prescalers */
    SIM_CLKDIV1  = SIM_CLKDIV1_OUTDIV4(1);
    SIM_CLKDIV1 |= SIM_CLKDIV1_OUTDIV1(1);
    /* First FEI must transition to FBE mode
        Enable external oscillator, RANGE=02, HGO=, EREFS=, LP=, IRCS= */
    MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK;

    /* Select external oscillator and Reference Divider and clear IREFS
     * to start external oscillator
     * CLKS = 2, FRDIV = 3, IREFS = 0, IRCLKEN = 0, IREFSTEN = 0
     */
    MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
   
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)0xE0U;
   
    /* MCG_C5: ??=0,PLLCLKEN=0,PLLSTEN=1,PRDIV=0x3, external clock reference = 8/4 = 2MHz */
    MCG_C5 = (uint8_t)0x23U;
   
    /* MCG_C6: LOLIE=0,PLLS=0,CME=0,VDIV=0x18 */
    MCG_C6 = (uint8_t)0x18U;
   
    while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
    }
   
    while((MCG_S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
    }
   
    /* Switch to PBE Mode */
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */
    MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
   
    /* MCG_C2: ??=0,??=0,RANGE=2,HGO=0,EREFS=0,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK;
   
    /* MCG_C5: ??=0,PLLCLKEN=0,PLLSTEN=1,PRDIV=0x03 */
    MCG_C5 = (uint8_t)0x23U;
   
    /* MCG_C6: LOLIE=0,PLLS=1,CME=0,VDIV=0x18 */
    MCG_C6 = (uint8_t)0x58U;
    while((MCG_S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
    }
    while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */
    }
    /* Switch to PEE Mode */
    /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */
    MCG_C1 = (uint8_t)0x18U;
   
    /* MCG_C2: ??=0,??=0,RANGE=2,HGO=0,EREFS=0,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK;

    /* MCG_C5: ??=0,PLLCLKEN=0,PLLSTEN=1,PRDIV=0x03 */
    MCG_C5 = (uint8_t)0x23U;
    /* MCG_C6: LOLIE=0,PLLS=1,CME=0,VDIV=0x18 */
    MCG_C6 = (uint8_t)0x58U;
    while((MCG_S & 0x0CU) != 0x0CU) {    /* Wait until output of the PLL is selected */
    }
    /* MCG_C6: CME=1 */
    MCG_C6 |= (uint8_t)0x20U;            /* Enable the clock monitor */
    /*** End of PE initialization code after reset ***/
    return 0;
/* end MCU_MKL25Z4 */
}
      USB_Init()
static void USB_Init(uint_8 controller_ID)
{
        if(controller_ID == MAX3353)
        {
#ifdef MCU_MK70F12
                /* MPU is disabled. All accesses from all bus masters are allowed */
                MPU_CESR=0;

                SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(1)         /** PLL0 reference */
                                   | SIM_SOPT2_USBFSRC(0)                        /** MCGPLLCLK as CLKC source */
                                  | SIM_SOPT2_USBF_CLKSEL_MASK;        /** USB fractional divider like USB reference clock */
                SIM_CLKDIV2 = USB_FRAC | USB_DIV;                /** Divide reference clock to obtain 48MHz */

                /* Enable USB-OTG IP clocking */
                SIM_SCGC4 |= SIM_SCGC4_USBFS_MASK;
#else
    #ifndef MCU_MKL25Z4
                SIM_CLKDIV2 &= (uint32_t)(~(SIM_CLKDIV2_USBFRAC_MASK | SIM_CLKDIV2_USBDIV_MASK));
    #endif /* MCU_MKL25Z4 */
    #ifdef MCGOUTCLK_72_MHZ
                /* Configure USBFRAC = 0, USBDIV = 0 => frq(USBout) = 2 / 3 * frq(PLLin) */
                SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC_MASK;
    #else
        #ifndef MCU_MKL25Z4
                /* Configure USBFRAC = 0, USBDIV = 0 => frq(USBout) = 1 / 1 * frq(PLLin) */
                SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0);
        #endif /* MCU_MKL25Z4 */
    #endif /* MCGOUTCLK_72_MHZ */

                /* 1. Configure USB to be clocked from PLL */
                SIM_SOPT2 |= SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK;

#if PLL_96
                /* 2. USB freq divider */
                SIM_CLKDIV2 = 0x02;
#endif /* PLL_96 */

                /* 3. Enable USB-OTG IP clocking */
                SIM_SCGC4 |= (SIM_SCGC4_USBOTG_MASK);      

                /* old documentation writes setting this bit is mandatory */
                USB0_USBTRC0 = 0x40;
               
                /* Configure enable USB regulator for device */
#if(defined MCU_MK20D5)               
                SIM_SOPT1CFG |= SIM_SOPT1CFG_URWE_MASK; /* Enable SOPT1 to be written */
#endif               
                SIM_SOPT1 |= SIM_SOPT1_USBREGEN_MASK;
}
#endif
     GPIO_Init()
static void GPIO_Init()
{   
#if defined(MCU_MKL25Z4)  
    /* Enable clock gating to PORTA, PORTB, PORTC, PORTD and PORTE */
    SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK
              | SIM_SCGC5_PORTB_MASK
              | SIM_SCGC5_PORTC_MASK
              | SIM_SCGC5_PORTD_MASK
              | SIM_SCGC5_PORTE_MASK);

    /* LEDs settings */
    PORTA_PCR5  =  PORT_PCR_MUX(1);
    PORTA_PCR16 =  PORT_PCR_MUX(1);
    PORTA_PCR17 =  PORT_PCR_MUX(1);
    PORTB_PCR8  =  PORT_PCR_MUX(1);

    GPIOA_PDDR |= (1<<5) | (1<<16) | (1<<17);
    GPIOB_PDDR |= (1<<8);

    /* Switch buttons settings */
    /* Set input on PORTC pin 3 */
#ifndef _USB_BATT_CHG_APP_H_
    PORTC_PCR3 =  PORT_PCR_MUX(1);
    GPIOC_PDDR &= ~((uint_32)1 << 3);
    /* Pull up enabled */
    PORTC_PCR3 |= PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
    /* GPIO_INT_EDGE_HIGH */
    PORTC_PCR3 |= PORT_PCR_IRQC(9);

    /* Set input on PORTA pin 4 */
    PORTA_PCR4 =  PORT_PCR_MUX(1);
    GPIOA_PDDR &= ~((uint_32)1 << 4);
    /* Pull up */
    PORTA_PCR4 |= PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
    /* GPIO_INT_EDGE_HIGH */
    PORTA_PCR4 |= PORT_PCR_IRQC(9);

    /* Clear interrupt flag */
    PORTC_ISFR = (1 << 3);
    PORTA_ISFR = (1 << 4);

    /* Enable interrupt port A */
    NVIC_ICPR = 1 << 30;
    NVIC_ISER = 1 << 30;
#endif
#endif
}
文档下载: 鼠标HID例程(上).pdf (371.33 KB)
参考文献:
[2] FreescaleUSB Stack Device API Reference Manual

相关帖子

沙发
FSL_TICS_Jeremy|  楼主 | 2014-9-15 11:07 | 只看该作者

如有什么错误或者不足,欢迎网友指正,请在后面跟帖!

使用特权

评论回复
板凳
qq4988| | 2014-9-15 11:26 | 只看该作者
赞一下

使用特权

评论回复
地板
jd972594| | 2014-9-16 08:54 | 只看该作者
谢谢楼主分享

使用特权

评论回复
5
choosechan| | 2014-10-25 23:01 | 只看该作者
谢谢楼主分享,不过官网提供的是5。0版本的,跟4.1.1架构有点不太一样。学习起来有点费劲。

使用特权

评论回复
6
FSL_TICS_Jeremy|  楼主 | 2014-10-30 10:08 | 只看该作者
choosechan 发表于 2014-10-25 23:01
谢谢楼主分享,不过官网提供的是5。0版本的,跟4.1.1架构有点不太一样。学习起来有点费劲。 ...

是的,架构是跟原来有些不同,但V5.0是未来的趋势,所以建议客户优先选择v5.0

使用特权

评论回复
7
choosechan| | 2014-10-31 21:57 | 只看该作者
选择了5.0就倒霉,里面的例程一编译就报错,解决了bug编译通过了,在开发板上又运行不了,汗!

使用特权

评论回复
8
niuyaliang| | 2014-12-28 15:24 | 只看该作者
学习学习

使用特权

评论回复
9
haolaishi| | 2014-12-28 15:51 | 只看该作者

使用特权

评论回复
10
sunmeat| | 2014-12-28 16:27 | 只看该作者
好东西

使用特权

评论回复
11
哆来咪| | 2015-1-25 19:15 | 只看该作者
多谢楼主分享啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

113

主题

2865

帖子

38

粉丝