查看: 2251|回复: 2

[原创] 【i.MX RT1010体验】+借助SDK几步配置USB CDC

  [复制链接]
  • TA的每日心情

    2024-2-5 12:06
  • 签到天数: 627 天

    [LV.9]以坛为家II

    94

    主题

    1628

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4429

    热心会员

    最后登录
    2024-2-5
    发表于 2021-4-10 08:51:12 | 显示全部楼层 |阅读模式
    RT1010_EVK板子 主打了音频功能和USB功能。我们今天就通过MCUXpresso 来配置生成代码。
    选择建好的工程,右击 管理组件

    MM1.png

    添加USB 组件
    MM2.png

    打开配置工具,配置USB对应的引脚
    MM4.png
    配置时钟:
    MM5.png
    添加外设组件到工程:
    MM7.png
    具体参数配置:
    MM8.png
    MM9.png
    MM11.png

    确定后,自动生成的对应的USB代码:
    MM3.png



    我们其余几乎不用管,只要对source里面的 "usb_device_interface_0_cic_vcom.h"和 "usb_device_interface_0_cic_vcom.c"c
    2个文件进行修改调用即可:
    我们看下C文件里面的代码:
    其中最重要的就是USB中断的回调函数:
    1. /*!
    2. * @brief Function that processes class specific events.
    3. *
    4. * @param handle Handle to USB device class.
    5. * @param event Class event code.
    6. * @param param        The parameter of the class specific event.
    7. * @return usb_status_t Status of USB transaction.
    8. */
    9. usb_status_t USB_DeviceInterface0CicVcomCallback(class_handle_t handle, uint32_t event, void *param)
    10. {
    11.     uint32_t len;
    12.     uint8_t *uartBitmap;
    13.     usb_device_cdc_acm_request_param_struct_t *acmReqParam;
    14.     usb_device_endpoint_callback_message_struct_t *epCbParam;
    15.     usb_status_t error = kStatus_USB_Error;
    16.     usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
    17.     acmReqParam = (usb_device_cdc_acm_request_param_struct_t *)param;
    18.     epCbParam = (usb_device_endpoint_callback_message_struct_t *)param;

    19.     switch (event)
    20.     {
    21.         case kUSB_DeviceCdcEventSendResponse:
    22.         {
    23.             if ((epCbParam->length != 0) && (!(epCbParam->length % g_UsbDeviceInterface1DicVcomSetting0DefaultEndpoints[USB_DIC_VCOM_IN_ENDPOINT_INDEX].maxPacketSize)))
    24.             {
    25.                 /* If the last packet is the size of endpoint, then send also zero-ended packet,
    26.                  ** meaning that we want to inform the host that we do not have any additional
    27.                  ** data, so it can flush the output.
    28.                  */
    29.                 error = USB_DeviceCdcAcmSend(handle, USB_DIC_VCOM_IN_ENDPOINT, NULL, 0);
    30.             }
    31.             else if ((1 == s_UsbDeviceComposite->attach) && (1 == s_UsbInterface0CicVcom.startTransactions))
    32.             {
    33.                 if ((epCbParam->buffer != NULL) || ((epCbParam->buffer == NULL) && (epCbParam->length == 0)))
    34.                 {
    35.                     /* User: add your own code for send complete event */
    36.                     /* Schedule buffer for next receive event */
    37.                     error = USB_DeviceCdcAcmRecv(handle, USB_DIC_VCOM_OUT_ENDPOINT, s_currRecvBuf,
    38.                                                  g_UsbDeviceInterface1DicVcomSetting0DefaultEndpoints[USB_DIC_VCOM_OUT_ENDPOINT_INDEX].maxPacketSize);
    39. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
    40.     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
    41.     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
    42.                     s_waitForDataReceive = 1;
    43.                     USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
    44. #endif
    45.                 }
    46.             }
    47.             else
    48.             {
    49.             }
    50.         }
    51.         break;
    52.         case kUSB_DeviceCdcEventRecvResponse:
    53.         {
    54.             if ((1 == s_UsbDeviceComposite->attach) && (1 == s_UsbInterface0CicVcom.startTransactions))
    55.             {
    56.                 s_recvSize = epCbParam->length;

    57. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
    58.     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
    59.     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
    60.                 s_waitForDataReceive = 0;
    61.                 USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK;
    62. #endif
    63.                 if (!s_recvSize)
    64.                 {
    65.                     /* Schedule buffer for next receive event */
    66.                     error = USB_DeviceCdcAcmRecv(handle, USB_DIC_VCOM_OUT_ENDPOINT, s_currRecvBuf,
    67.                                                  g_UsbDeviceInterface1DicVcomSetting0DefaultEndpoints[USB_DIC_VCOM_OUT_ENDPOINT_INDEX].maxPacketSize);
    68. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
    69.     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
    70.     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
    71.                     s_waitForDataReceive = 1;
    72.                     USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
    73. #endif
    74.                 }
    75.             }
    76.         }
    77.         break;
    78.         case kUSB_DeviceCdcEventSerialStateNotif:
    79.             ((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 0;
    80.             error = kStatus_USB_Success;
    81.             break;
    82.         case kUSB_DeviceCdcEventSendEncapsulatedCommand:
    83.             break;
    84.         case kUSB_DeviceCdcEventGetEncapsulatedResponse:
    85.             break;
    86.         case kUSB_DeviceCdcEventSetCommFeature:
    87.             if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
    88.             {
    89.                 if (1 == acmReqParam->isSetup)
    90.                 {
    91.                     *(acmReqParam->buffer) = s_abstractState;
    92.                 }
    93.                 else
    94.                 {
    95.                     *(acmReqParam->length) = 0;
    96.                 }
    97.             }
    98.             else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
    99.             {
    100.                 if (1 == acmReqParam->isSetup)
    101.                 {
    102.                     *(acmReqParam->buffer) = s_countryCode;
    103.                 }
    104.                 else
    105.                 {
    106.                     *(acmReqParam->length) = 0;
    107.                 }
    108.             }
    109.             else
    110.             {
    111.             }
    112.             error = kStatus_USB_Success;
    113.             break;
    114.         case kUSB_DeviceCdcEventGetCommFeature:
    115.             if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
    116.             {
    117.                 *(acmReqParam->buffer) = s_abstractState;
    118.                 *(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
    119.             }
    120.             else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
    121.             {
    122.                 *(acmReqParam->buffer) = s_countryCode;
    123.                 *(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
    124.             }
    125.             else
    126.             {
    127.             }
    128.             error = kStatus_USB_Success;
    129.             break;
    130.         case kUSB_DeviceCdcEventClearCommFeature:
    131.             break;
    132.         case kUSB_DeviceCdcEventGetLineCoding:
    133.             *(acmReqParam->buffer) = s_lineCoding;
    134.             *(acmReqParam->length) = LINE_CODING_SIZE;
    135.             error = kStatus_USB_Success;
    136.             break;
    137.         case kUSB_DeviceCdcEventSetLineCoding:
    138.             if (1 == acmReqParam->isSetup)
    139.             {
    140.                 *(acmReqParam->buffer) = s_lineCoding;
    141.             }
    142.             else
    143.             {
    144.                 *(acmReqParam->length) = 0;
    145.             }
    146.             error = kStatus_USB_Success;
    147.             break;
    148.         case kUSB_DeviceCdcEventSetControlLineState:
    149.         {
    150.             s_usbCdcAcmInfo.dteStatus = acmReqParam->setupValue;
    151.             /* activate/deactivate Tx carrier */
    152.             if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
    153.             {
    154.                 acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
    155.             }
    156.             else
    157.             {
    158.                 acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
    159.             }

    160.             /* activate carrier and DTE. Com port of terminal tool running on PC is open now */
    161.             if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
    162.             {
    163.                 acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
    164.             }
    165.             /* Com port of terminal tool running on PC is closed now */
    166.             else
    167.             {
    168.                 acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
    169.             }

    170.             /* Indicates to DCE if DTE is present or not */
    171.             acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? true : false;

    172.             /* Initialize the serial state buffer */
    173.             acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE;                /* bmRequestType */
    174.             acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_NOTIF_SERIAL_STATE; /* bNotification */
    175.             acmInfo->serialStateBuf[2] = 0x00;                              /* wValue */
    176.             acmInfo->serialStateBuf[3] = 0x00;
    177.             acmInfo->serialStateBuf[4] = 0x00; /* wIndex */
    178.             acmInfo->serialStateBuf[5] = 0x00;
    179.             acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */
    180.             acmInfo->serialStateBuf[7] = 0x00;
    181.             /* Notify to host the line state */
    182.             acmInfo->serialStateBuf[4] = acmReqParam->interfaceIndex;
    183.             /* Lower byte of UART BITMAP */
    184.             uartBitmap = (uint8_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
    185.             uartBitmap[0] = acmInfo->uartState & 0xFFu;
    186.             uartBitmap[1] = (acmInfo->uartState >> 8) & 0xFFu;
    187.             len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
    188.             if (0 == ((usb_device_cdc_acm_struct_t *)handle)->hasSentState)
    189.             {
    190.                 error = USB_DeviceCdcAcmSend(handle, USB_CIC_VCOM_IN_ENDPOINT, acmInfo->serialStateBuf, len);
    191.                 if (kStatus_USB_Success != error)
    192.                 {
    193.                     usb_echo("kUSB_DeviceCdcEventSetControlLineState error!");
    194.                 }
    195.                 ((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 1;
    196.             }

    197.             /* Update status */
    198.             if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
    199.             {
    200.                 /*  To do: CARRIER_ACTIVATED */
    201.             }
    202.             else
    203.             {
    204.                 /* To do: CARRIER_DEACTIVATED */
    205.             }
    206.             if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
    207.             {
    208.                 /* DTE_ACTIVATED */
    209.                 if (1 == s_UsbDeviceComposite->attach)
    210.                 {
    211.                     s_UsbInterface0CicVcom.startTransactions = 1;
    212. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
    213.     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
    214.     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
    215.                     s_waitForDataReceive = 1;
    216.                     USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
    217.                     s_comOpen = 1;
    218.                     usb_echo("USB_APP_CDC_DTE_ACTIVATED\r\n");
    219. #endif
    220.                 }
    221.             }
    222.             else
    223.             {
    224.                 /* DTE_DEACTIVATED */
    225.                 if (1 == s_UsbDeviceComposite->attach)
    226.                 {
    227.                     s_UsbInterface0CicVcom.startTransactions = 0;
    228.                 }
    229.             }
    230.         }
    231.         break;
    232.         case kUSB_DeviceCdcEventSendBreak:
    233.             break;
    234.         default:
    235.             break;
    236.     }

    237.     return error;
    238. }
    复制代码
    对应POINT中断的事件都有对应的处理,我们可以将自己的中断事件,写入。
    C文件里面还提供了一个实例TAST:
    1. /*!
    2. * @brief Interface task function.
    3. */
    4. void USB_DeviceInterface0CicVcomTask(void)
    5. {
    6.         uint8_t tmpdata[DATA_BUFF_SIZE];
    7.         uint8_t tmpdata2[DATA_BUFF_SIZE];
    8.         int32_t i,j;
    9.     usb_status_t error = kStatus_USB_Error;
    10.     if ((1 == s_UsbDeviceComposite->attach) && (1 == s_UsbInterface0CicVcom.startTransactions))
    11.     {
    12.         /* User Code */
    13.         if ((0 != s_recvSize) && (0xFFFFFFFFU != s_recvSize))
    14.         {

    15.             j=0;
    16.             /* Copy Buffer to Send Buff */
    17.             for (i = 0; i < s_recvSize; i++)
    18.             {
    19.                 s_currSendBuf[s_sendSize++] = s_currRecvBuf[i];
    20.                 tmpdata[j++] = s_currRecvBuf[i];
    21.             }
    22.             s_recvSize = 0;
    23.         }

    24. /*        if (s_sendSize)
    25.         {
    26.             uint32_t size = s_sendSize;
    27.             s_sendSize = 0;

    28.             error = USB_DeviceCdcAcmSend(s_UsbInterface0CicVcom.cdcAcmHandle, USB_DIC_VCOM_IN_ENDPOINT, s_currSendBuf, size);

    29.             if (error != kStatus_USB_Success)
    30.             {
    31.                 // Failure to send Data Handling code here
    32.             }
    33.         }*/
    34.         //命令格式SSXXPP  XX代表数字
    35.              if((tmpdata[0]==0x53)&&(tmpdata[1]==0x53)&&(tmpdata[j-2]==0x50)&&(tmpdata[j-1]==0x50))
    36.                 {
    37.                      //USB_DeviceCdcAcmSend(s_UsbInterface0CicVcom.cdcAcmHandle, USB_DIC_VCOM_IN_ENDPOINT, tmpdata, j);

    38.                         if(tmpdata[2]==0x31)
    39.                         {
    40.                                 USB_CDC_SendStr("LED ON\r\n");
    41.                         }
    42.                         else if (tmpdata[2]==0x32)
    43.                         {
    44.                                 USB_CDC_SendStr("LED OFF\r\n");
    45.                         }
    46.                         else
    47.                         {
    48.                                 sprintf(tmpdata2,"CMD ERR,YOU SEND MESSAGE IS %s\r\n",tmpdata);
    49.                                 USB_CDC_SendStr(tmpdata2);
    50.                         }

    51.                         tmpdata[0]=0;
    52.                         tmpdata[1]=0;
    53.                 }



    54. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
    55.     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
    56.     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
    57.         if ((s_waitForDataReceive))
    58.         {
    59.             if (s_comOpen == 1)
    60.             {
    61.                 /* Wait for all the packets been sent during opening the com port. Otherwise these packets may
    62.                                         * wake up the system.
    63.                 */
    64.                 usb_echo("Waiting to enter lowpower ...\r\n");
    65.                 for (uint32_t i = 0U; i < 16000000U; ++i)
    66.                 {
    67.                     __ASM("NOP"); /* delay */
    68.                 }

    69.                 s_comOpen = 0;
    70.             }
    71.             usb_echo("Enter lowpower\r\n");
    72.             BOARD_DbgConsole_Deinit();
    73.             USB0->INTEN &= ~USB_INTEN_TOKDNEEN_MASK;
    74.             USB_EnterLowpowerMode();

    75.             s_waitForDataReceive = 0;
    76.             USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK;
    77.             BOARD_DbgConsole_Init();
    78.             usb_echo("Exit  lowpower\r\n");
    79.         }
    80. #endif
    81.     }
    82. }
    复制代码
    我们在这里修改也可以,目前默认的就是把接收到的数据再次发送回去。
    我们可以对接收的数据进行分析,完成对应事件的处理。这样一个基于USB CDC的通讯系统就完成了。
    这里封装了一个USB CDC的发送函数:
    1. void USB_CDC_SendStr(char* Str)
    2. {
    3.         if(strlen(Str)>DATA_BUFF_SIZE) return;
    4.         USB_DeviceCdcAcmSend(s_UsbInterface0CicVcom.cdcAcmHandle, USB_DIC_VCOM_IN_ENDPOINT,(uint8_t*) Str, strlen(Str));
    5. }
    复制代码
    然后我们在main函数while循环里面调用即可:
    1. USB_DeviceInterface0CicVcomTask();
    复制代码
    好了USB CDC的使用就到这里了。
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-10 22:38
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2021-4-10 13:37:33 | 显示全部楼层
    借助官方库来开发USB就显得非常容易了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    4 天前
  • 签到天数: 557 天

    [LV.9]以坛为家II

    34

    主题

    5913

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    5688
    最后登录
    2024-4-19
    发表于 2021-4-13 13:38:33 | 显示全部楼层
    偷个楼
    借助官方库来开发USB就显得非常容易了
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-23 18:47 , Processed in 0.121336 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表