[DemoCode下载] M031的USB打印机

[复制链接]
2008|6
 楼主| xuanhuanzi 发表于 2019-6-23 18:51 | 显示全部楼层 |阅读模式
  1. /******************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
  4. * $Revision: 10 $
  5. * $Date: 18/07/18 3:37p $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    Demonstrate how to implement a composite device.(USB micro printer device and HID Transfer).
  7. *           Transfer data between USB device and PC through USB HID interface.
  8. *           A windows tool is also included in this sample code to connect with a USB device.
  9. *
  10. * @note
  11. *           Windows tool: User need to input the specific PID for the USB HID device connected to PC.
  12. *                         PID format with hexadecimal.
  13. *
  14. *           -> PID is 0xAABB in this sample.
  15. *
  16. * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  17. *****************************************************************************/
  18. #include <stdio.h>
  19. #include "M031Series.h"
  20. #include "micro_printer_and_hid_transfer.h"

  21. #define CRYSTAL_LESS        1    /* CRYSTAL_LESS must be 1 if USB clock source is HIRC */
  22. #define TRIM_INIT           (SYS_BASE+0x118)

  23. extern uint8_t volatile g_u8Suspend;
  24. int IsDebugFifoEmpty(void);

  25. void SYS_Init(void)
  26. {
  27.     /* Unlock protected registers */
  28.     SYS_UnlockReg();

  29.     /* Enable HIRC clock */
  30.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

  31.     /* Waiting for HIRC clock ready */
  32.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

  33.     /* Switch HCLK clock source to HIRC and HCLK source divide 1 */
  34.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

  35.     /* Switch UART0 clock source to HIRC */
  36.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));

  37.     /* Enable UART0 clock */
  38.     CLK_EnableModuleClock(UART0_MODULE);

  39.     /* Switch USB clock source to HIRC & USB Clock = HIRC / 1 */
  40.     CLK_SetModuleClock(USBD_MODULE, CLK_CLKSEL0_USBDSEL_HIRC, CLK_CLKDIV0_USB(1));

  41.     /* Enable USB clock */
  42.     CLK_EnableModuleClock(USBD_MODULE);

  43.     /* Update System Core Clock */
  44.     SystemCoreClockUpdate();

  45.     /* Set PB multi-function pins for UART0 RXD=PB.12 and TXD=PB.13 */
  46.     SYS->GPB_MFPH = (SYS->GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk))
  47.                     |(SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

  48.     /* Lock protected registers */
  49.     SYS_LockReg();
  50. }

  51. void PowerDown()
  52. {
  53.     /* Unlock protected registers */
  54.     SYS_UnlockReg();

  55.     printf("Enter power down ...\n");
  56.     while(!IsDebugFifoEmpty());

  57.     /* Wakeup Enable */
  58.     USBD_ENABLE_INT(USBD_INTEN_WKEN_Msk);

  59.     CLK_PowerDown();

  60.     /* Clear PWR_DOWN_EN if it is not clear by itself */
  61.     if(CLK->PWRCTL & CLK_PWRCTL_PDEN_Msk)
  62.         CLK->PWRCTL ^= CLK_PWRCTL_PDEN_Msk;

  63.     printf("device wakeup!\n");

  64.     /* Lock protected registers */
  65.     SYS_LockReg();
  66. }

  67. /*---------------------------------------------------------------------------------------------------------*/
  68. /*  Main Function                                                                                          */
  69. /*---------------------------------------------------------------------------------------------------------*/
  70. int32_t main(void)
  71. {
  72. #if CRYSTAL_LESS
  73.     uint32_t u32TrimInit;
  74. #endif
  75.     uint8_t Str[9];

  76.     /* Unlock protected registers */
  77.     SYS_UnlockReg();

  78.     /* Init System, peripheral clock and multi-function I/O */
  79.     SYS_Init();

  80.     /* Init UART0 to 115200-8n1 for print message */
  81.     UART_Open(UART0, 115200);

  82.     printf("\n");
  83.     printf("+-------------------------------------------------------+\n");
  84.     printf("|       NuMicro USB Composite Device Sample Code        |\n");
  85.     printf("|      USB Micro Printer + HID Transfer (PID:AABB)      |\n");
  86.     printf("+-------------------------------------------------------+\n");

  87.     /* Open USB controller */
  88.     USBD_Open(&gsInfo, PTR_ClassRequest, NULL);

  89.     /* Endpoint configuration */
  90.     PTR_Init();

  91.     /* Start USB device */
  92.     USBD_Start();

  93. #if CRYSTAL_LESS
  94.     /* Backup init trim */
  95.     u32TrimInit = M32(TRIM_INIT);

  96.     /* Waiting for USB bus stable */
  97.     USBD_CLR_INT_FLAG(USBD_INTSTS_SOFIF_Msk);
  98.     while((USBD_GET_INT_FLAG() & USBD_INTSTS_SOFIF_Msk) == 0);

  99.     /* Enable USB crystal-less - Set reference clock from USB SOF packet & Enable HIRC auto trim function */
  100.     SYS->HIRCTRIMCTL |= (SYS_HIRCTRIMCTL_REFCKSEL_Msk | 0x1);
  101. #endif

  102.     NVIC_EnableIRQ(USBD_IRQn);

  103.     while(1)
  104.     {
  105.         /* Enter power down when USB suspend */
  106.         if(g_u8Suspend)
  107.             PowerDown();

  108.         CLK_SysTickDelay(2000);   // delay

  109.         if (++Str[1] > 0x39)
  110.             Str[1] = 0x30;      // increase 1 to 10 than reset to 0

  111. #if CRYSTAL_LESS
  112.         /* Re-start crystal-less when any error found */
  113.         if (SYS->HIRCTRIMSTS & (SYS_HIRCTRIMSTS_TFAILIF_Msk | SYS_HIRCTRIMSTS_CLKERIF_Msk))
  114.         {
  115.             SYS->HIRCTRIMSTS = SYS_HIRCTRIMSTS_TFAILIF_Msk | SYS_HIRCTRIMSTS_CLKERIF_Msk;

  116.             /* Init TRIM */
  117.             M32(TRIM_INIT) = u32TrimInit;

  118.             /* Waiting for USB bus stable */
  119.             USBD_CLR_INT_FLAG(USBD_INTSTS_SOFIF_Msk);
  120.             while((USBD_GET_INT_FLAG() & USBD_INTSTS_SOFIF_Msk) == 0);

  121.             /* Re-enable crystal-less - Set reference clock from USB SOF packet & Enable HIRC auto trim function */
  122.             SYS->HIRCTRIMCTL |= (SYS_HIRCTRIMCTL_REFCKSEL_Msk | 0x1);
  123.             //printf("USB trim fail. Just retry. SYS->HIRCTRIMSTS = 0x%x, SYS->HIRCTRIMCTL = 0x%x\n", SYS->HIRCTRIMSTS, SYS->HIRCTRIMCTL);
  124.         }
  125. #endif
  126.     }
  127. }



  128. /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/



 楼主| xuanhuanzi 发表于 2019-6-23 18:52 | 显示全部楼层
  1. /******************************************************************************
  2. * @file     micro_printer_and_hid_transfer.h
  3. * @version  V1.00
  4. * $Revision: 4 $
  5. * $Date: 18/04/03 10:29a $
  6. * @brief    M031 series USB driver header file
  7. *
  8. * @note
  9. * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  10. *****************************************************************************/

  11. #ifndef __USBD_PRINTER_H__
  12. #define __USBD_PRINTER_H__

  13. /* Define the vendor id and product id */
  14. #define USBD_VID        0x0416
  15. #define USBD_PID        0xAABB

  16. /*!<Define CDC Class Specific Request */
  17. #define SET_LINE_CODE           0x20
  18. #define GET_LINE_CODE           0x21
  19. #define SET_CONTROL_LINE_STATE  0x22

  20. /*!<Define HID Class Specific Request */
  21. #define GET_REPORT          0x01
  22. #define GET_IDLE            0x02
  23. #define GET_PROTOCOL        0x03
  24. #define SET_REPORT          0x09
  25. #define SET_IDLE            0x0A
  26. #define SET_PROTOCOL        0x0B

  27. /*!<USB HID Interface Class protocol */
  28. #define HID_NONE            0x00
  29. #define HID_KEYBOARD        0x01
  30. #define HID_MOUSE           0x02

  31. /*!<USB HID Class Report Type */
  32. #define HID_RPT_TYPE_INPUT      0x01
  33. #define HID_RPT_TYPE_OUTPUT     0x02
  34. #define HID_RPT_TYPE_FEATURE    0x03

  35. /*-------------------------------------------------------------*/
  36. /* Define EP maximum packet size */
  37. #define EP0_MAX_PKT_SIZE    64
  38. #define EP1_MAX_PKT_SIZE    EP0_MAX_PKT_SIZE
  39. #define EP2_MAX_PKT_SIZE    64
  40. #define EP3_MAX_PKT_SIZE    64
  41. #define EP4_MAX_PKT_SIZE    8
  42. #define EP5_MAX_PKT_SIZE    64
  43. #define EP6_MAX_PKT_SIZE    64

  44. #define SETUP_BUF_BASE      0
  45. #define SETUP_BUF_LEN       8
  46. #define EP0_BUF_BASE        (SETUP_BUF_BASE + SETUP_BUF_LEN)
  47. #define EP0_BUF_LEN         EP0_MAX_PKT_SIZE
  48. #define EP1_BUF_BASE        (SETUP_BUF_BASE + SETUP_BUF_LEN)
  49. #define EP1_BUF_LEN         EP1_MAX_PKT_SIZE
  50. #define EP2_BUF_BASE        (EP1_BUF_BASE + EP1_BUF_LEN)
  51. #define EP2_BUF_LEN         EP2_MAX_PKT_SIZE
  52. #define EP3_BUF_BASE        (EP2_BUF_BASE + EP2_BUF_LEN)
  53. #define EP3_BUF_LEN         EP3_MAX_PKT_SIZE
  54. #define EP4_BUF_BASE        (EP3_BUF_BASE + EP3_BUF_LEN)
  55. #define EP4_BUF_LEN         EP4_MAX_PKT_SIZE
  56. #define EP5_BUF_BASE        (EP4_BUF_BASE + EP4_BUF_LEN)
  57. #define EP5_BUF_LEN         EP5_MAX_PKT_SIZE
  58. #define EP6_BUF_BASE        (EP5_BUF_BASE + EP5_BUF_LEN)
  59. #define EP6_BUF_LEN         EP6_MAX_PKT_SIZE

  60. /* Define the interrupt In EP number */
  61. #define BULK_IN_EP_NUM      0x01
  62. #define BULK_OUT_EP_NUM     0x02
  63. #define INT_IN_EP_NUM       0x03
  64. #define INT_IN_EP_NUM_1     0x04
  65. #define INT_OUT_EP_NUM      0x05

  66. /* Define Descriptor information */
  67. #define HID_DEFAULT_INT_IN_INTERVAL     1
  68. #define USBD_SELF_POWERED               0
  69. #define USBD_REMOTE_WAKEUP              0
  70. #define USBD_MAX_POWER                  50  /* The unit is in 2mA. ex: 50 * 2mA = 100mA */

  71. /************************************************/
  72. #define  GET_PORT_STATUS           0x01


  73. /*-------------------------------------------------------------*/
  74. void PTR_Init(void);
  75. void PTR_ClassRequest(void);
  76. void PTR_Data_Receive(void);

  77. void EP5_Handler(void);
  78. void EP6_Handler(void);
  79. void HID_SetInReport(void);
  80. void HID_GetOutReport(uint8_t *pu8EpBuf, uint32_t u32Size);

  81. #endif  /* __USBD_PRINTER_H_ */

  82. /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/
 楼主| xuanhuanzi 发表于 2019-6-23 18:52 | 显示全部楼层
  1. /******************************************************************************
  2. * @file     micro_printer_and_hid_transfer.c
  3. * @version  V1.00
  4. * $Revision: 10 $
  5. * $Date: 18/07/18 4:49p $
  6. * @brief    M031 series USBD driver Sample file
  7. *
  8. * @note
  9. * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  10. *****************************************************************************/
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "NuMicro.h"
  14. #include "micro_printer_and_hid_transfer.h"

  15. uint8_t volatile g_u8Suspend = 0;

  16. /*--------------------------------------------------------------------------*/
  17. void USBD_IRQHandler(void)
  18. {
  19.     uint32_t volatile u32IntSts = USBD_GET_INT_FLAG();
  20.     uint32_t volatile u32State = USBD_GET_BUS_STATE();

  21.     if (u32IntSts & USBD_INTSTS_FLDET)
  22.     {
  23.         /* Floating detect */
  24.         USBD_CLR_INT_FLAG(USBD_INTSTS_FLDET);

  25.         if (USBD_IS_ATTACHED())
  26.         {
  27.             /* USB Plug In */
  28.             USBD_ENABLE_USB();
  29.         }
  30.         else
  31.         {
  32.             /* USB Un-plug */
  33.             USBD_DISABLE_USB();
  34.         }
  35.     }

  36.     if (u32IntSts & USBD_INTSTS_BUS)
  37.     {
  38.         /* Clear event flag */
  39.         USBD_CLR_INT_FLAG(USBD_INTSTS_BUS);

  40.         if (u32State & USBD_STATE_USBRST)
  41.         {
  42.             /* Bus reset */
  43.             USBD_ENABLE_USB();
  44.             USBD_SwReset();
  45.             g_u8Suspend = 0;
  46.         }
  47.         if (u32State & USBD_STATE_SUSPEND)
  48.         {
  49.             /* Enter power down to wait USB attached */
  50.             g_u8Suspend = 1;

  51.             /* Enable USB but disable PHY */
  52.             USBD_DISABLE_PHY();
  53.         }
  54.         if (u32State & USBD_STATE_RESUME)
  55.         {
  56.             /* Enable USB and enable PHY */
  57.             USBD_ENABLE_USB();
  58.             g_u8Suspend = 0;
  59.         }
  60.     }

  61.     if(u32IntSts & USBD_INTSTS_SOF)
  62.     {
  63.         /* Clear SOF flag */
  64.         USBD_CLR_INT_FLAG(USBD_INTSTS_SOF);
  65.     }

  66.     if(u32IntSts & USBD_INTSTS_WAKEUP)
  67.     {
  68.         /* Clear event flag */
  69.         USBD_CLR_INT_FLAG(USBD_INTSTS_WAKEUP);
  70.     }

  71.     if (u32IntSts & USBD_INTSTS_USB)
  72.     {
  73.         /* USB event */
  74.         if (u32IntSts & USBD_INTSTS_SETUP)
  75.         {
  76.             /* Setup packet */
  77.             /* Clear event flag */
  78.             USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP);

  79.             /* Clear the data IN/OUT ready flag of control end-points */
  80.             USBD_STOP_TRANSACTION(EP0);
  81.             USBD_STOP_TRANSACTION(EP1);

  82.             USBD_ProcessSetupPacket();
  83.         }

  84.         /* EP events */
  85.         if (u32IntSts & USBD_INTSTS_EP0)
  86.         {
  87.             /* Clear event flag */
  88.             USBD_CLR_INT_FLAG(USBD_INTSTS_EP0);
  89.             /* control IN */
  90.             USBD_CtrlIn();
  91.         }

  92.         if (u32IntSts & USBD_INTSTS_EP1)
  93.         {
  94.             /* Clear event flag */
  95.             USBD_CLR_INT_FLAG(USBD_INTSTS_EP1);
  96.             /* control OUT */
  97.             USBD_CtrlOut();
  98.         }

  99.         if (u32IntSts & USBD_INTSTS_EP2)
  100.         {
  101.             /* Clear event flag */
  102.             USBD_CLR_INT_FLAG(USBD_INTSTS_EP2);
  103.         }

  104.         if (u32IntSts & USBD_INTSTS_EP3)
  105.         {
  106.             /* Clear event flag */
  107.             USBD_CLR_INT_FLAG(USBD_INTSTS_EP3);
  108.             /* Bulk Out -> receive printer data */
  109.             PTR_Data_Receive();
  110.         }

  111.         if (u32IntSts & USBD_INTSTS_EP4)
  112.         {
  113.             /* Clear event flag */
  114.             USBD_CLR_INT_FLAG(USBD_INTSTS_EP4);
  115.         }

  116.         if (u32IntSts & USBD_INTSTS_EP5)
  117.         {
  118.             /* Clear event flag */
  119.             USBD_CLR_INT_FLAG(USBD_INTSTS_EP5);
  120.             /* Interrupt IN */
  121.             EP5_Handler();
  122.         }

  123.         if (u32IntSts & USBD_INTSTS_EP6)
  124.         {
  125.             /* Clear event flag */
  126.             USBD_CLR_INT_FLAG(USBD_INTSTS_EP6);
  127.             /* Interrupt OUT */
  128.             EP6_Handler();
  129.         }

  130.         if (u32IntSts & USBD_INTSTS_EP7)
  131.         {
  132.             /* Clear event flag */
  133.             USBD_CLR_INT_FLAG(USBD_INTSTS_EP7);
  134.         }
  135.     }
  136. }

  137. void EP5_Handler(void)  /* Interrupt IN handler */
  138. {
  139.     HID_SetInReport();
  140. }

  141. void EP6_Handler(void)  /* Interrupt OUT handler */
  142. {
  143.     uint8_t *ptr;
  144.     /* Interrupt OUT */
  145.     ptr = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP6));
  146.     HID_GetOutReport(ptr, USBD_GET_PAYLOAD_LEN(EP6));
  147.     USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE);
  148. }

  149. /*--------------------------------------------------------------------------*/
  150. /**
  151.   * @brief  USBD Endpoint Config.
  152.   * @param  None.
  153.   * @retval None.
  154.   */
  155. void PTR_Init(void)
  156. {
  157.     /* Init setup packet buffer */
  158.     /* Buffer for setup packet -> [0 ~ 0x7] */
  159.     USBD->STBUFSEG = SETUP_BUF_BASE;

  160.     /*****************************************************/
  161.     /* EP0 ==> control IN endpoint, address 0 */
  162.     USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0);
  163.     /* Buffer range for EP0 */
  164.     USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE);

  165.     /* EP1 ==> control OUT endpoint, address 0 */
  166.     USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0);
  167.     /* Buffer range for EP1 */
  168.     USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE);

  169.     /*****************************************************/
  170.     /* EP2 ==> Bulk IN endpoint, address 1 */
  171.     USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | BULK_IN_EP_NUM);
  172.     /* Buffer offset for EP2 */
  173.     USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE);

  174.     /* EP3 ==> Bulk Out endpoint, address 2 */
  175.     USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | BULK_OUT_EP_NUM);
  176.     /* Buffer offset for EP3 */
  177.     USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE);
  178.     /* trigger receive OUT data */
  179.     USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);

  180.     /* EP4 ==> Interrupt IN endpoint, address 3 */
  181.     USBD_CONFIG_EP(EP4, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM);
  182.     /* Buffer offset for EP4 ->  */
  183.     USBD_SET_EP_BUF_ADDR(EP4, EP4_BUF_BASE);

  184.     /*****************************************************/
  185.     /* EP5 ==> Interrupt IN endpoint, address 4 */
  186.     USBD_CONFIG_EP(EP5, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM_1);
  187.     /* Buffer range for EP5 */
  188.     USBD_SET_EP_BUF_ADDR(EP5, EP5_BUF_BASE);

  189.     /* EP6 ==> Interrupt OUT endpoint, address 5 */
  190.     USBD_CONFIG_EP(EP6, USBD_CFG_EPMODE_OUT | INT_OUT_EP_NUM);
  191.     /* Buffer range for EP6 */
  192.     USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE);
  193.     /* trigger to receive OUT data */
  194.     USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE);
  195. }

  196. void PTR_ClassRequest(void)
  197. {
  198.     uint8_t buf[8];

  199.     USBD_GetSetupPacket(buf);

  200.     if (buf[0] & 0x80)   /* request data transfer direction */
  201.     {
  202.         /* Device to host */
  203.         switch (buf[1])
  204.         {
  205.         case GET_PORT_STATUS:
  206.         {
  207.             /* Data stage */
  208.             USBD_SET_DATA1(EP0);
  209.             USBD_SET_PAYLOAD_LEN(EP0, 0);
  210.             /* Status stage */
  211.             USBD_PrepareCtrlOut(0,0);
  212.             break;
  213.         }
  214.         default:
  215.         {
  216.             /* Setup error, stall the device */
  217.             USBD_SetStall(EP0);
  218.             USBD_SetStall(EP1);
  219.             break;
  220.         }
  221.         }
  222.     }
  223.     else
  224.     {
  225.         /* Host to device */
  226.         switch (buf[1])
  227.         {
  228.         case SET_REPORT:
  229.         {
  230.             if (buf[3] == 3)
  231.             {
  232.                 /* Request Type = Feature */
  233.                 USBD_SET_DATA1(EP1);
  234.                 USBD_SET_PAYLOAD_LEN(EP1, 0);
  235.             }
  236.             break;
  237.         }
  238.         case SET_IDLE:
  239.         {
  240.             /* Status stage */
  241.             USBD_SET_DATA1(EP0);
  242.             USBD_SET_PAYLOAD_LEN(EP0, 0);
  243.             break;
  244.         }
  245.         case SET_PROTOCOL:
  246. //             {
  247. //                 break;
  248. //             }
  249.         default:
  250.         {
  251.             /* Stall */
  252.             /* Setup error, stall the device */
  253.             USBD_SetStall(EP0);
  254.             USBD_SetStall(EP1);
  255.             break;
  256.         }
  257.         }
  258.     }
  259. }

  260. /* Receive printer command and data from host */
  261. void PTR_Data_Receive(void)
  262. {
  263.     uint8_t *pu8Buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP3));
  264.     uint32_t u32Size = USBD_GET_PAYLOAD_LEN(EP3);

  265.     /* trigger next OUT data */
  266.     USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
  267. }

  268. /***************************************************************/
  269. #define HID_CMD_SIGNATURE   0x43444948

  270. /* HID Transfer Commands */
  271. #define HID_CMD_NONE     0x00
  272. #define HID_CMD_ERASE    0x71
  273. #define HID_CMD_READ     0xD2
  274. #define HID_CMD_WRITE    0xC3
  275. #define HID_CMD_TEST     0xB4

  276. #define PAGE_SIZE        2048
  277. #define TEST_PAGES       4
  278. #define SECTOR_SIZE      4096
  279. #define START_SECTOR     0x10

  280. #ifdef __ICCARM__
  281. typedef __packed struct
  282. {
  283.     uint8_t u8Cmd;
  284.     uint8_t u8Size;
  285.     uint32_t u32Arg1;
  286.     uint32_t u32Arg2;
  287.     uint32_t u32Signature;
  288.     uint32_t u32Checksum;
  289. } CMD_T;

  290. #else
  291. typedef struct __attribute__((__packed__))
  292. {
  293.     uint8_t u8Cmd;
  294.     uint8_t u8Size;
  295.     uint32_t u32Arg1;
  296.     uint32_t u32Arg2;
  297.     uint32_t u32Signature;
  298.     uint32_t u32Checksum;
  299. }
  300. CMD_T;
  301. #endif

  302. CMD_T gCmd;

  303. static uint8_t  g_u8PageBuff[PAGE_SIZE] = {0};    /* Page buffer to upload/download through HID report */
  304. static uint32_t g_u32BytesInPageBuf = 0;          /* The bytes of data in g_u8PageBuff */
  305. static uint8_t  g_u8TestPages[TEST_PAGES * PAGE_SIZE] = {0};    /* Test pages to upload/download through HID report */

  306. int32_t HID_CmdEraseSectors(CMD_T *pCmd)
  307. {
  308.     uint32_t u32StartSector;
  309.     uint32_t u32Sectors;

  310.     u32StartSector = pCmd->u32Arg1 - START_SECTOR;
  311.     u32Sectors = pCmd->u32Arg2;

  312.     printf("Erase command - Sector: %d   Sector Cnt: %d\n", u32StartSector, u32Sectors);

  313.     /* TODO: To erase the sector of storage */
  314.     memset(g_u8TestPages + u32StartSector * SECTOR_SIZE, 0xFF, sizeof(uint8_t) * u32Sectors * SECTOR_SIZE);

  315.     /* To note the command has been done */
  316.     pCmd->u8Cmd = HID_CMD_NONE;

  317.     return 0;
  318. }


  319. int32_t HID_CmdReadPages(CMD_T *pCmd)
  320. {
  321.     uint32_t u32StartPage;
  322.     uint32_t u32Pages;

  323.     u32StartPage = pCmd->u32Arg1;
  324.     u32Pages     = pCmd->u32Arg2;

  325.     printf("Read command - Start page: %d    Pages Numbers: %d\n", u32StartPage, u32Pages);

  326.     if(u32Pages)
  327.     {
  328.         /* Update data to page buffer to upload */
  329.         /* TODO: We need to update the page data if got a page read command. (0xFF is used in this sample code) */
  330.         memcpy(g_u8PageBuff, g_u8TestPages, sizeof(g_u8PageBuff));
  331.         g_u32BytesInPageBuf = PAGE_SIZE;

  332.         /* The signature word is used as page counter */
  333.         pCmd->u32Signature = 1;

  334.         /* Trigger HID IN */
  335.         USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5)), (void *)g_u8PageBuff, EP5_MAX_PKT_SIZE);
  336.         USBD_SET_PAYLOAD_LEN(EP5, EP5_MAX_PKT_SIZE);
  337.         g_u32BytesInPageBuf -= EP5_MAX_PKT_SIZE;
  338.     }

  339.     return 0;
  340. }


  341. int32_t HID_CmdWritePages(CMD_T *pCmd)
  342. {
  343.     uint32_t u32StartPage;
  344.     uint32_t u32Pages;

  345.     u32StartPage = pCmd->u32Arg1;
  346.     u32Pages     = pCmd->u32Arg2;

  347.     printf("Write command - Start page: %d    Pages Numbers: %d\n", u32StartPage, u32Pages);
  348.     g_u32BytesInPageBuf = 0;

  349.     /* The signature is used to page counter */
  350.     pCmd->u32Signature = 0;

  351.     return 0;
  352. }


  353. int32_t gi32CmdTestCnt = 0;
  354. int32_t HID_CmdTest(CMD_T *pCmd)
  355. {
  356.     int32_t i;
  357.     uint8_t *pu8;

  358.     pu8 = (uint8_t *)pCmd;
  359.     printf("Get test command #%d (%d bytes)\n", gi32CmdTestCnt++, pCmd->u8Size);
  360.     for(i=0; i<pCmd->u8Size; i++)
  361.     {
  362.         if((i&0xF) == 0)
  363.         {
  364.             printf("\n");
  365.         }
  366.         printf(" %02x", pu8[i]);
  367.     }

  368.     printf("\n");


  369.     /* To note the command has been done */
  370.     pCmd->u8Cmd = HID_CMD_NONE;

  371.     return 0;
  372. }


  373. uint32_t CalCheckSum(uint8_t *buf, uint32_t size)
  374. {
  375.     uint32_t sum;
  376.     int32_t i;

  377.     i = 0;
  378.     sum = 0;
  379.     while(size--)
  380.     {
  381.         sum+=buf[i++];
  382.     }

  383.     return sum;

  384. }


  385. int32_t ProcessCommand(uint8_t *pu8Buffer, uint32_t u32BufferLen)
  386. {
  387.     uint32_t u32sum;


  388.     USBD_MemCopy((uint8_t *)&gCmd, pu8Buffer, u32BufferLen);

  389.     /* Check size */
  390.     if((gCmd.u8Size > sizeof(gCmd)) || (gCmd.u8Size > u32BufferLen))
  391.         return -1;

  392.     /* Check signature */
  393.     if(gCmd.u32Signature != HID_CMD_SIGNATURE)
  394.         return -1;

  395.     /* Calculate checksum & check it*/
  396.     u32sum = CalCheckSum((uint8_t *)&gCmd, gCmd.u8Size);
  397.     if(u32sum != gCmd.u32Checksum)
  398.         return -1;

  399.     switch(gCmd.u8Cmd)
  400.     {
  401.     case HID_CMD_ERASE:
  402.     {
  403.         HID_CmdEraseSectors(&gCmd);
  404.         break;
  405.     }
  406.     case HID_CMD_READ:
  407.     {
  408.         HID_CmdReadPages(&gCmd);
  409.         break;
  410.     }
  411.     case HID_CMD_WRITE:
  412.     {
  413.         HID_CmdWritePages(&gCmd);
  414.         break;
  415.     }
  416.     case HID_CMD_TEST:
  417.     {
  418.         HID_CmdTest(&gCmd);
  419.         break;
  420.     }
  421.     default:
  422.         return -1;
  423.     }

  424.     return 0;
  425. }


  426. void HID_GetOutReport(uint8_t *pu8EpBuf, uint32_t u32Size)
  427. {
  428.     uint8_t  u8Cmd;
  429.     uint32_t u32StartPage;
  430.     uint32_t u32Pages;
  431.     uint32_t u32PageCnt;

  432.     /* Get command information */
  433.     u8Cmd        = gCmd.u8Cmd;
  434.     u32StartPage = gCmd.u32Arg1;
  435.     u32Pages     = gCmd.u32Arg2;
  436.     u32PageCnt   = gCmd.u32Signature; /* The signature word is used to count pages */


  437.     /* Check if it is in the data phase of write command */
  438.     if((u8Cmd == HID_CMD_WRITE) &&  (u32PageCnt < u32Pages))
  439.     {
  440.         /* Process the data phase of write command */

  441.         /* Get data from HID OUT */
  442.         USBD_MemCopy(&g_u8PageBuff[g_u32BytesInPageBuf], pu8EpBuf, EP6_MAX_PKT_SIZE);
  443.         g_u32BytesInPageBuf += EP6_MAX_PKT_SIZE;

  444.         /* The HOST must make sure the data is PAGE_SIZE alignment */
  445.         if(g_u32BytesInPageBuf >= PAGE_SIZE)
  446.         {
  447.             printf("Writing page %d\n", u32StartPage + u32PageCnt);
  448.             /* TODO: We should program received data to storage here */
  449.             memcpy(g_u8TestPages + u32PageCnt * PAGE_SIZE, g_u8PageBuff, sizeof(g_u8PageBuff));
  450.             u32PageCnt++;

  451.             /* Write command complete! */
  452.             if(u32PageCnt >= u32Pages)
  453.             {
  454.                 u8Cmd = HID_CMD_NONE;

  455.                 printf("Write command complete.\n");
  456.             }

  457.             g_u32BytesInPageBuf = 0;
  458.         }

  459.         /* Update command status */
  460.         gCmd.u8Cmd        = u8Cmd;
  461.         gCmd.u32Signature = u32PageCnt;
  462.     }
  463.     else
  464.     {
  465.         /* Check and process the command packet */
  466.         if(ProcessCommand(pu8EpBuf, u32Size))
  467.         {
  468.             printf("Unknown HID command!\n");
  469.         }
  470.     }
  471. }

  472. void HID_SetInReport(void)
  473. {
  474.     uint32_t u32StartPage;
  475.     uint32_t u32TotalPages;
  476.     uint32_t u32PageCnt;
  477.     uint8_t *ptr;
  478.     uint8_t u8Cmd;

  479.     u8Cmd        = gCmd.u8Cmd;
  480.     u32StartPage = gCmd.u32Arg1;
  481.     u32TotalPages= gCmd.u32Arg2;
  482.     u32PageCnt   = gCmd.u32Signature;

  483.     /* Check if it is in data phase of read command */
  484.     if(u8Cmd == HID_CMD_READ)
  485.     {
  486.         /* Process the data phase of read command */
  487.         if((u32PageCnt >= u32TotalPages) && (g_u32BytesInPageBuf == 0))
  488.         {
  489.             /* The data transfer is complete. */
  490.             u8Cmd = HID_CMD_NONE;
  491.             printf("Read command complete!\n");
  492.         }
  493.         else
  494.         {
  495.             if(g_u32BytesInPageBuf == 0)
  496.             {
  497.                 /* The previous page has sent out. Read new page to page buffer */
  498.                 /* TODO: We should update new page data here. (0xFF is used in this sample code) */
  499.                 printf("Reading page %d\n", u32StartPage + u32PageCnt);
  500.                 memcpy(g_u8PageBuff, g_u8TestPages + u32PageCnt * PAGE_SIZE, sizeof(g_u8PageBuff));

  501.                 g_u32BytesInPageBuf = PAGE_SIZE;

  502.                 /* Update the page counter */
  503.                 u32PageCnt++;
  504.             }

  505.             /* Prepare the data for next HID IN transfer */
  506.             ptr = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5));
  507.             USBD_MemCopy(ptr, (void *)&g_u8PageBuff[PAGE_SIZE - g_u32BytesInPageBuf], EP5_MAX_PKT_SIZE);
  508.             USBD_SET_PAYLOAD_LEN(EP5, EP5_MAX_PKT_SIZE);
  509.             g_u32BytesInPageBuf -= EP5_MAX_PKT_SIZE;
  510.         }
  511.     }

  512.     gCmd.u8Cmd        = u8Cmd;
  513.     gCmd.u32Signature = u32PageCnt;
  514. }
 楼主| xuanhuanzi 发表于 2019-6-23 18:52 | 显示全部楼层
  1. /******************************************************************************
  2. * @file     descriptors.c
  3. * @version  V1.00
  4. * $Revision: 6 $
  5. * $Date: 18/04/13 3:44p $
  6. * @brief    M031 series USBD driver source file
  7. *
  8. * @note
  9. * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  10. *****************************************************************************/
  11. /*!<Includes */
  12. #include "NuMicro.h"
  13. #include "micro_printer_and_hid_transfer.h"

  14. /*----------------------------------------------------------------------------*/
  15. /*!<USB Device Descriptor */
  16. uint8_t gu8DeviceDescriptor[] =
  17. {
  18.     LEN_DEVICE,     /* bLength */
  19.     DESC_DEVICE,    /* bDescriptorType */
  20.     0x10, 0x01,     /* bcdUSB */
  21.     0x00,           /* bDeviceClass */
  22.     0x00,           /* bDeviceSubClass */
  23.     0x00,           /* bDeviceProtocol */
  24.     EP0_MAX_PKT_SIZE,   /* bMaxPacketSize0 */
  25.     /* idVendor */
  26.     USBD_VID & 0x00FF,
  27.     ((USBD_VID & 0xFF00) >> 8),
  28.     /* idProduct */
  29.     USBD_PID & 0x00FF,
  30.     ((USBD_PID & 0xFF00) >> 8),
  31.     0x00, 0x03,     /* bcdDevice */
  32.     0x01,           /* iManufacture */
  33.     0x02,           /* iProduct */
  34.     0x00,           /* iSerialNumber - no serial */
  35.     0x01            /* bNumConfigurations */
  36. };

  37. /*!<USB HID Report Descriptor */
  38. uint8_t HID_DeviceReportDescriptor[] =
  39. {
  40.     0x06, 0x00, 0xFF,   // Usage Page = 0xFF00 (Vendor Defined Page 1)
  41.     0x09, 0x01,         // Usage (Vendor Usage 1)
  42.     0xA1, 0x01,         // Collection (Application)
  43.     0x19, 0x01,         // Usage Minimum
  44.     0x29, 0x40,         // Usage Maximum //64 input usages total (0x01 to 0x40)
  45.     0x15, 0x00,         // Logical Minimum (data bytes in the report may have minimum value = 0x00)
  46.     0x26, 0xFF, 0x00,   // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255)
  47.     0x75, 0x08,         // Report Size: 8-bit field size
  48.     0x95, 0x40,         // Report Count: Make sixty-four 8-bit fields (the next time the parser hits
  49.     // an "Input", "Output", or "Feature" item)
  50.     0x81, 0x00,         // Input (Data, Array, Abs): Instantiates input packet fields based on the
  51.     // above report size, count, logical min/max, and usage.
  52.     0x19, 0x01,         // Usage Minimum
  53.     0x29, 0x40,         // Usage Maximum //64 output usages total (0x01 to 0x40)
  54.     0x91, 0x00,         // Output (Data, Array, Abs): Instantiates output packet fields. Uses same
  55.     // report size and count as "Input" fields, since nothing new/different was
  56.     // specified to the parser since the "Input" item.
  57.     0xC0                // End Collection
  58. };


  59. /*!<USB Configure Descriptor */
  60. uint8_t gu8ConfigDescriptor[] =
  61. {
  62.     LEN_CONFIG,     /* bLength              */
  63.     DESC_CONFIG,    /* bDescriptorType      */
  64.     0x6E, 0x00,     /* wTotalLength         */
  65.     0x02,           /* bNumInterfaces       */
  66.     0x01,           /* bConfigurationValue  */
  67.     0x00,           /* iConfiguration       */
  68.     0xC0,           /* bmAttributes         */
  69.     0x32,           /* MaxPower             */

  70.     /* INTERFACE descriptor */
  71.     LEN_INTERFACE,  /* bLength                        */
  72.     DESC_INTERFACE, /* bDescriptorType                */
  73.     0x00,           /* bInterfaceNumber               */
  74.     0x00,           /* bAlternateSetting              */
  75.     0x01,           /* bNumEndpoints                  */
  76.     0x07,           /* bInterfaceClass: printer class */
  77.     0x01,           /* bInterfaceSubClass             */
  78.     0x01,           /* bInterfaceProtocol             */
  79.     0x00,           /* iInterface                     */

  80.     /* ENDPOINT descriptor */
  81.     LEN_ENDPOINT,                   /* bLength          */
  82.     DESC_ENDPOINT,                  /* bDescriptorType  */
  83.     (EP_OUTPUT | BULK_OUT_EP_NUM),  /* bEndpointAddress */
  84.     EP_BULK,                        /* bmAttributes     */
  85.     EP3_MAX_PKT_SIZE, 0x00,         /* wMaxPacketSize   */
  86.     0x00,                           /* bInterval        */

  87.     /* INTERFACE descriptor */
  88.     LEN_INTERFACE,  /* bLength                        */
  89.     DESC_INTERFACE, /* bDescriptorType                */
  90.     0x00,           /* bInterfaceNumber               */
  91.     0x01,           /* bAlternateSetting              */
  92.     0x02,           /* bNumEndpoints                  */
  93.     0x07,           /* bInterfaceClass: printer class */
  94.     0x01,           /* bInterfaceSubClass             */
  95.     0x02,           /* bInterfaceProtocol             */
  96.     0x00,           /* iInterface                     */

  97.     /* ENDPOINT descriptor */
  98.     LEN_ENDPOINT,                   /* bLength          */
  99.     DESC_ENDPOINT,                  /* bDescriptorType  */
  100.     (EP_OUTPUT | BULK_OUT_EP_NUM),  /* bEndpointAddress */
  101.     EP_BULK,                        /* bmAttributes     */
  102.     EP3_MAX_PKT_SIZE, 0x00,         /* wMaxPacketSize   */
  103.     0x00,                           /* bInterval        */

  104.     /* ENDPOINT descriptor */
  105.     LEN_ENDPOINT,                   /* bLength          */
  106.     DESC_ENDPOINT,                  /* bDescriptorType  */
  107.     (EP_INPUT | BULK_IN_EP_NUM),    /* bEndpointAddress */
  108.     EP_BULK,                        /* bmAttributes     */
  109.     EP2_MAX_PKT_SIZE, 0x00,         /* wMaxPacketSize   */
  110.     0x00,                           /* bInterval        */

  111.     /* INTERFACE descriptor */
  112.     LEN_INTERFACE,  /* bLength              */
  113.     DESC_INTERFACE, /* bDescriptorType      */
  114.     0x00,           /* bInterfaceNumber     */
  115.     0x02,           /* bAlternateSetting    */
  116.     0x03,           /* bNumEndpoints        */
  117.     0xFF,           /* bInterfaceClass      */
  118.     0x00,           /* bInterfaceSubClass   */
  119.     0xFF,           /* bInterfaceProtocol   */
  120.     0x00,           /* iInterface           */

  121.     /* ENDPOINT descriptor */
  122.     LEN_ENDPOINT,                   /* bLength          */
  123.     DESC_ENDPOINT,                  /* bDescriptorType  */
  124.     (EP_OUTPUT | BULK_OUT_EP_NUM),  /* bEndpointAddress */
  125.     EP_BULK,                        /* bmAttributes     */
  126.     EP3_MAX_PKT_SIZE, 0x00,         /* wMaxPacketSize   */
  127.     0x00,                           /* bInterval        */

  128.     /* ENDPOINT descriptor */
  129.     LEN_ENDPOINT,                   /* bLength          */
  130.     DESC_ENDPOINT,                  /* bDescriptorType  */
  131.     (EP_INPUT | BULK_IN_EP_NUM),    /* bEndpointAddress */
  132.     EP_BULK,                        /* bmAttributes     */
  133.     EP2_MAX_PKT_SIZE, 0x00,         /* wMaxPacketSize   */
  134.     0x00,                           /* bInterval        */

  135.     /* ENDPOINT descriptor */
  136.     LEN_ENDPOINT,                   /* bLength          */
  137.     DESC_ENDPOINT,                  /* bDescriptorType  */
  138.     (EP_INPUT | INT_IN_EP_NUM),     /* bEndpointAddress */
  139.     EP_INT,                         /* bmAttributes     */
  140.     EP4_MAX_PKT_SIZE, 0x00,         /* wMaxPacketSize   */
  141.     0x01,                           /* bInterval        */

  142.     /* I/F descr: HID Transfer */
  143.     LEN_INTERFACE,  /* bLength */
  144.     DESC_INTERFACE, /* bDescriptorType */
  145.     0x01,           /* bInterfaceNumber */
  146.     0x00,           /* bAlternateSetting */
  147.     0x02,           /* bNumEndpoints */
  148.     0x03,           /* bInterfaceClass */
  149.     0x00,           /* bInterfaceSubClass */
  150.     0x00,           /* bInterfaceProtocol */
  151.     0x00,           /* iInterface */

  152.     /* HID Descriptor */
  153.     LEN_HID,        /* Size of this descriptor in UINT8s. */
  154.     DESC_HID,       /* HID descriptor type. */
  155.     0x10, 0x01,     /* HID Class Spec. release number. */
  156.     0x00,           /* H/W target country. */
  157.     0x01,           /* Number of HID class descriptors to follow. */
  158.     DESC_HID_RPT,   /* Descriptor type. */
  159.     /* Total length of report descriptor. */
  160.     sizeof(HID_DeviceReportDescriptor) & 0x00FF,
  161.     ((sizeof(HID_DeviceReportDescriptor) & 0xFF00) >> 8),

  162.     /* EP Descriptor: interrupt in. */
  163.     LEN_ENDPOINT,                               /* bLength */
  164.     DESC_ENDPOINT,                              /* bDescriptorType */
  165.     (INT_IN_EP_NUM_1 | EP_INPUT),               /* bEndpointAddress */
  166.     EP_INT,                                     /* bmAttributes */
  167.     /* wMaxPacketSize */
  168.     EP5_MAX_PKT_SIZE & 0x00FF,
  169.     ((EP5_MAX_PKT_SIZE & 0xFF00) >> 8),
  170.     HID_DEFAULT_INT_IN_INTERVAL,                /* bInterval */

  171.     /* EP Descriptor: interrupt out. */
  172.     LEN_ENDPOINT,                               /* bLength */
  173.     DESC_ENDPOINT,                              /* bDescriptorType */
  174.     (INT_OUT_EP_NUM | EP_OUTPUT),               /* bEndpointAddress */
  175.     EP_INT,                                     /* bmAttributes */
  176.     /* wMaxPacketSize */
  177.     EP6_MAX_PKT_SIZE & 0x00FF,
  178.     ((EP6_MAX_PKT_SIZE & 0xFF00) >> 8),
  179.     HID_DEFAULT_INT_IN_INTERVAL,                /* bInterval */
  180. };

  181. /*!<USB Language String Descriptor */
  182. uint8_t gu8StringLang[4] =
  183. {
  184.     4,              /* bLength */
  185.     DESC_STRING,    /* bDescriptorType */
  186.     0x09, 0x04
  187. };

  188. /*!<USB Vendor String Descriptor */
  189. uint8_t gu8VendorStringDesc[] =
  190. {
  191.     16,
  192.     DESC_STRING,
  193.     'N', 0, 'u', 0, 'v', 0, 'o', 0, 't', 0, 'o', 0, 'n', 0
  194. };

  195. /*!<USB Product String Descriptor */
  196. uint8_t gu8ProductStringDesc[] =
  197. {
  198.     22,             /* bLength          */
  199.     DESC_STRING,    /* bDescriptorType  */
  200.     'U', 0, 'S', 0, 'B', 0, ' ', 0, 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0
  201. };

  202. /*!<USB BOS Descriptor */
  203. const uint8_t gu8BOSDescriptor[] =
  204. {
  205.     LEN_BOS,        /* bLength */
  206.     DESC_BOS,       /* bDescriptorType */
  207.     /* wTotalLength */
  208.     0x0C & 0x00FF,
  209.     ((0x0C & 0xFF00) >> 8),
  210.     0x01,           /* bNumDeviceCaps */

  211.     /* Device Capability */
  212.     0x7,            /* bLength */
  213.     DESC_CAPABILITY,/* bDescriptorType */
  214.     CAP_USB20_EXT,  /* bDevCapabilityType */
  215.     0x02, 0x00, 0x00, 0x00  /* bmAttributes */
  216. };

  217. uint8_t *gpu8UsbString[4] =
  218. {
  219.     gu8StringLang,
  220.     gu8VendorStringDesc,
  221.     gu8ProductStringDesc,
  222.     0,
  223. };

  224. uint8_t *gu8UsbHidReport[3] =
  225. {
  226.     0,
  227.     HID_DeviceReportDescriptor,
  228.     0,
  229. };

  230. uint32_t gu32UsbHidReportLen[3] =
  231. {
  232.     0,
  233.     sizeof(HID_DeviceReportDescriptor),
  234.     0,
  235. };

  236. uint32_t gu32ConfigHidDescIdx[3] =
  237. {
  238.     0,
  239.     (sizeof(gu8ConfigDescriptor) - LEN_HID - (2*LEN_ENDPOINT)),
  240.     0,
  241. };

  242. const S_USBD_INFO_T gsInfo =
  243. {
  244.     (uint8_t *)gu8DeviceDescriptor,
  245.     (uint8_t *)gu8ConfigDescriptor,
  246.     (uint8_t **)gpu8UsbString,
  247.     (uint8_t **)gu8UsbHidReport,
  248.     (uint8_t *)gu8BOSDescriptor,
  249.     (uint32_t *)gu32UsbHidReportLen,
  250.     (uint32_t *)gu32ConfigHidDescIdx
  251. };

 楼主| xuanhuanzi 发表于 2019-6-23 19:05 | 显示全部楼层
这是官方BSP里面的例子,说明这个系列还是非常支持USB的。
643757107 发表于 2019-6-23 23:29 | 显示全部楼层
多谢分享,一会儿下载看看。
dongnanxibei 发表于 2019-6-23 23:52 | 显示全部楼层
新唐提供的USB接口的芯片还挺多的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

183

主题

2331

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部