wuyage

移植 ARM CMSIS USB Stack的CDC类到飞思卡尔Kinetis KL26[Keil]

0
阅读(2920)

     同事Jicheng 在其blog http://comm.chinaaet.com/adi/blogdetail/39877.html 中详细的介绍了如何移植ARM CMSIS USB Stack的CDC类到Kinetis 上,不过它是基于IAR移植的。实际还有相当多的客户使用Keil开发环境,我在移植到Keil的过程中花费了不少时间,所以在这里我将移植后的工程分享给大家,如果大家使用Keil开发USB CDC,可以直接在其上面开发或者将其中的相关文件移植到自己的原有工程中。

    附件中两个工程,一个是在官方的FRDM_KL26 SC代码上移植的,另外一个是在优龙KL26的代码基础上移植的。

    另外补充说明两点:

    1、移植过程中USB时钟部分很关键,一定要确保为48M

    USB 48M.jpg

    如果选择PEE模式,那么需要保证PLL的输出为96M。这样  OUTDIV1=1,OUTDIV4=3 以保证内核时钟为48M,Bus Clock为24M。


 2.http://comm.chinaaet.com/adi/blogdetail/39877.html  中介绍的工作方式是在while(1)里不断用查询方式获取CDC的数据,

while(1) 
{
    cnt = USBD_CDC_ACM_DataRead(ch, 64);
    if(cnt!=0)
      USBD_CDC_ACM_DataSend(ch, cnt);				
 }

在实际使用过程中,客户更希望使用的方式是在中断服务里接收数据。

这种方式可以通过以下步骤实现:

1)对USBD_CDC_ACM_EP_BULKOUT_HandleData()函数进行修改:

static void USBD_CDC_ACM_EP_BULKOUT_HandleData () {     
  int32_t len_received;   
  len_received = USBD_ReadEP(usbd_cdc_acm_ep_bulkout, ptr_data_received);
  usb_recv_proc(ptr_data_received,len_received);  // 处理函数
  
#if 0  
if ((usbd_cdc_acm_receivebuf_sz - (ptr_data_received - USBD_CDC_ACM_ReceiveBuf)) >= usbd_cdc_acm_maxpacketsize1[USBD_HighSpeed]) {
                                        /* If there is space for 1 max packet */
                                        /* Read received packet to receive buf*/
    len_received       = USBD_ReadEP(usbd_cdc_acm_ep_bulkout, ptr_data_received);
    ptr_data_received += len_received;  /* Correct pointer to received data   */
    if (data_received_pending_pckts &&  /* If packet was pending              */
       !data_receive_int_access) {      /* and not interrupt access           */
      data_received_pending_pckts--;    /* Decrement pending packets number   */
    }
  } else {
    data_no_space_for_receive = 1;      /* There is no space in receive buffer
                                           for the newly received data        */
    if (data_receive_int_access) {      /* If this access is from interrupt
                                           function                           */
      data_received_pending_pckts++;    /* then this is new unhandled packet  */
    }
  }  
#endif
  
}
void usb_recv_proc(uint8_t * buf,uint16_t len)	// USB 接收数据处理函数
{
	usb_send_buf(buf, len);	//将接收到的数据发送出去
}

该方法具体代码可以参考附件中YL_USB_CDC_Demo。



YL_USB_CDC_Demo.rar

FRDM-KL26Z_SC_USBCDC.rar