Browse Source

update CSL library (#8370)

Xian Wu 1 year ago
parent
commit
4018092baf
57 changed files with 3835 additions and 1519 deletions
  1. 0 5
      bsp/synwit/swm320/README.md
  2. 1 1
      bsp/synwit/swm320/drivers/drv_uart.c
  3. 52 10
      bsp/synwit/swm320/libraries/CMSIS/DeviceSupport/SWM320.h
  4. 16 179
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.c
  5. 15 25
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.h
  6. 3 42
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.c
  7. 15 3
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.h
  8. 20 208
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.c
  9. 13 20
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.h
  10. 5 0
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdio.c
  11. 2 2
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.c
  12. 3 2
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.h
  13. 26 307
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.c
  14. 13 30
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.h
  15. 20 122
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.c
  16. 11 13
      bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.h
  17. 2 0
      bsp/synwit/swm320/rtconfig.h
  18. 0 5
      bsp/synwit/swm341/README.md
  19. 3 2
      bsp/synwit/swm341/drivers/drv_sdram.c
  20. 1 1
      bsp/synwit/swm341/drivers/drv_uart.c
  21. 77 23
      bsp/synwit/swm341/libraries/CMSIS/DeviceSupport/SWM341.h
  22. 2 2
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_adc.c
  23. 18 3
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.c
  24. 12 8
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.h
  25. 5 2
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dac.c
  26. 106 17
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.c
  27. 18 5
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.h
  28. 4 4
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma2d.c
  29. 4 43
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.c
  30. 17 3
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.h
  31. 1 1
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_lcd.c
  32. 24 208
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.c
  33. 16 20
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.h
  34. 275 2
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.c
  35. 27 0
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.h
  36. 3 3
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.c
  37. 23 21
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.h
  38. 82 5
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.c
  39. 3 0
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.h
  40. 3 26
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.c
  41. 4 2
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.h
  42. 28 115
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.c
  43. 12 13
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.h
  44. 6 0
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usb.h
  45. 2 1
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usbh.c
  46. 26 4
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.c
  47. 1 0
      bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.h
  48. 119 2
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.c
  49. 14 1
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.h
  50. 1366 0
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.c
  51. 153 0
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.h
  52. 376 0
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.c
  53. 758 0
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.h
  54. 23 6
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.c
  55. 2 0
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.h
  56. 2 2
      bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_stdreq.c
  57. 2 0
      bsp/synwit/swm341/rtconfig.h

+ 0 - 5
bsp/synwit/swm320/README.md

@@ -157,11 +157,6 @@ msh />
 | NOR FLASH          |     支持     | NOR FLASH                             |
 | CAN                |    暂不支持   |                                       |
 
-## 维护人信息
-
-- [yanmowudi](https://github.com/yanmowudi)
-- [邮箱](lik@synwit.cn)
-
 ## 参考资料
 
 * [RT-Thread 文档中心](https://www.rt-thread.org/document/site/)

+ 1 - 1
bsp/synwit/swm320/drivers/drv_uart.c

@@ -277,7 +277,7 @@ static void rt_hw_uart_isr(struct rt_serial_device *serial_device)
     uart_cfg = serial_device->parent.user_data;
 
     /* UART in mode Receiver -------------------------------------------------*/
-    if (UART_INTRXThresholdStat(uart_cfg->UARTx) || UART_INTTimeoutStat(uart_cfg->UARTx))
+    if (UART_INTStat(uart_cfg->UARTx, UART_IT_RX_THR) || UART_INTStat(uart_cfg->UARTx, UART_IT_RX_TOUT))
     {
         rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_IND);
     }

+ 52 - 10
bsp/synwit/swm320/libraries/CMSIS/DeviceSupport/SWM320.h

@@ -105,6 +105,7 @@ typedef enum IRQn
 #endif
 
 #include <stdio.h>
+#include <stdbool.h>
 #include "core_cm4.h"                  /* Cortex-M0 processor and core peripherals           */
 #include "system_SWM320.h"
 
@@ -177,8 +178,6 @@ typedef struct {
 
     __IO uint32_t BODIE;
     __IO uint32_t BODIF;
-
-    __IO uint32_t ADC1IN7;
 } SYS_TypeDef;
 
 
@@ -359,11 +358,6 @@ typedef struct {
 #define SYS_BODIF_2V2_Pos           1       //BOD 2.2V等级触发中断状态,写1清零
 #define SYS_BODIF_2V2_Msk           (0x01 << SYS_BODIF_2V2_Pos)
 
-#define SYS_ADC1IN7_SEL_Pos         0       //ADC1模块模拟通道7,1 温度传感器    2 电池电压    3 RTC电源域BG    4 主电源域BG   5 PDM33
-#define SYS_ADC1IN7_SEL_Msk         (0x0F << SYS_ADC1IN7_SEL_Pos)
-#define SYS_ADC1IN7_IOON_Pos        4       //ADC1模块模拟通道7所用IO开关
-#define SYS_ADC1IN7_IOON_Msk        (0x01 << SYS_ADC1IN7_IOON_Pos)
-
 
 
 
@@ -1472,11 +1466,11 @@ typedef struct {
 #define SPI_IE_RFOVF_Msk            (0x01 << SPI_IE_RFOVF_Pos)
 #define SPI_IE_RFF_Pos              1
 #define SPI_IE_RFF_Msk              (0x01 << SPI_IE_RFF_Pos)
-#define SPI_IE_RFHF_Pos             2
+#define SPI_IE_RFHF_Pos             2       //~rxfifo_full & (rxfifo_level == 4)
 #define SPI_IE_RFHF_Msk             (0x01 << SPI_IE_RFHF_Pos)
 #define SPI_IE_TFE_Pos              3
 #define SPI_IE_TFE_Msk              (0x01 << SPI_IE_TFE_Pos)
-#define SPI_IE_TFHF_Pos             4
+#define SPI_IE_TFHF_Pos             4       //~txfifo_full & (txfifo_level == 4)
 #define SPI_IE_TFHF_Msk             (0x01 << SPI_IE_TFHF_Pos)
 #define SPI_IE_WTC_Pos              8       //Word Transmit Complete
 #define SPI_IE_WTC_Msk              (0x01 << SPI_IE_WTC_Pos)
@@ -2712,7 +2706,7 @@ typedef struct {
 typedef struct {
     __IO uint32_t DATA;
     __IO uint32_t ADDR;
-    __IO uint32_t FLASH_ERASE;
+    __IO uint32_t ERASE;
     __IO uint32_t CACHE;
     __IO uint32_t CFG0;
     __IO uint32_t CFG1;
@@ -3178,4 +3172,52 @@ typedef void (* Func_void_void) (void);
 #include "SWM320_wdt.h"
 
 
+
+#ifdef  SW_LOG_RTT
+#define log_printf(...)     SEGGER_RTT_printf(0, __VA_ARGS__)
+#else
+#define log_printf(...)     printf(__VA_ARGS__)
+#endif
+
+
+#ifndef SW_LOG_LEVEL
+#define SW_LOG_LEVEL        0
+#endif
+
+#if (SW_LOG_LEVEL > 0)
+#define SW_LOG_ERR(...)     {                        \
+                            log_printf("ERROR: ");   \
+                            log_printf(__VA_ARGS__); \
+                            log_printf("\n");        \
+                            }
+
+#if (SW_LOG_LEVEL > 1)
+#define SW_LOG_WARN(...)    {                        \
+                            log_printf("WARN : ");   \
+                            log_printf(__VA_ARGS__); \
+                            log_printf("\n");        \
+                            }
+
+#if (SW_LOG_LEVEL > 2)
+#define SW_LOG_INFO(...)    {                        \
+                            log_printf("INFO : ");   \
+                            log_printf(__VA_ARGS__); \
+                            log_printf("\n");        \
+                            }
+#else
+#define SW_LOG_INFO(...)
+#endif
+
+#else
+#define SW_LOG_WARN(...)
+#define SW_LOG_INFO(...)
+#endif
+
+#else
+#define SW_LOG_ERR(...)
+#define SW_LOG_WARN(...)
+#define SW_LOG_INFO(...)
+#endif
+
+
 #endif //__SWM320_H__

+ 16 - 179
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.c

@@ -388,209 +388,46 @@ void CAN_SetFilter16b(CAN_TypeDef * CANx, uint16_t check1, uint16_t mask1, uint1
 }
 
 /******************************************************************************************************************************************
-* 函数名称: CAN_INTRXNotEmptyEn()
-* 功能说明: 当RX FIFO中有数据时(非空)触发中断使能
+* 函数名称: CAN_INTEn()
+* 功能说明: 使能指定中断
 * 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
+*           uint32_t it         interrupt type,有效值包括 CAN_IT_RX_NOTEMPTY、CAN_IT_RX_OVERFLOW、CAN_IT_TX_EMPTY、CAN_IT_ARBLOST、
+*                               CAN_IT_ERR、CAN_IT_ERR_WARN、CAN_IT_ERR_PASS、CAN_IT_WAKEUP 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void CAN_INTRXNotEmptyEn(CAN_TypeDef * CANx)
+void CAN_INTEn(CAN_TypeDef * CANx, uint32_t it)
 {
-    CANx->IE |= (1 << CAN_IE_RXDA_Pos);
+    CANx->IE |= it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: CAN_INTRXNotEmptyDis()
-* 功能说明: 当RX FIFO中有数据时(非空)触发中断禁止
+* 函数名称: CAN_INTDis()
+* 功能说明: 关闭指定中断
 * 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
+*           uint32_t it         interrupt type,有效值包括 CAN_IT_RX_NOTEMPTY、CAN_IT_RX_OVERFLOW、CAN_IT_TX_EMPTY、CAN_IT_ARBLOST、
+*                               CAN_IT_ERR、CAN_IT_ERR_WARN、CAN_IT_ERR_PASS、CAN_IT_WAKEUP 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void CAN_INTRXNotEmptyDis(CAN_TypeDef * CANx)
+void CAN_INTDis(CAN_TypeDef * CANx, uint32_t it)
 {
-    CANx->IE &= ~(1 << CAN_IE_RXDA_Pos);
+    CANx->IE &= ~it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: CAN_INTTXBufEmptyEn()
-* 功能说明: 当TX Buffer空时触发中断使能
+* 函数名称: CAN_INTClr()
+* 功能说明: 清除中断标志
 * 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
+*           uint32_t it         interrupt type,有效值包括 CAN_IT_RX_OVERFLOW
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void CAN_INTTXBufEmptyEn(CAN_TypeDef * CANx)
-{
-    CANx->IE |= (1 << CAN_IE_TXBR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTTXBufEmptyDis()
-* 功能说明: 当TX Buffer空时触发中断禁止
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTTXBufEmptyDis(CAN_TypeDef * CANx)
-{
-    CANx->IE &= ~(1 << CAN_IE_TXBR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTErrWarningEn()
-* 功能说明: TXERR/RXERR计数值达到Error Warning Limit时触发中断使能
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTErrWarningEn(CAN_TypeDef * CANx)
-{
-    CANx->IE |= (1 << CAN_IE_ERRWARN_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTErrWarningDis()
-* 功能说明: TXERR/RXERR计数值达到Error Warning Limit时触发中断禁止
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTErrWarningDis(CAN_TypeDef * CANx)
-{
-    CANx->IE &= ~(1 << CAN_IE_ERRWARN_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTRXOverflowEn()
-* 功能说明: RX FIFO 溢出时触发中断使能
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTRXOverflowEn(CAN_TypeDef * CANx)
-{
-    CANx->IE |= (1 << CAN_IE_RXOV_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTRXOverflowDis()
-* 功能说明: RX FIFO 溢出时触发中断禁止
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTRXOverflowDis(CAN_TypeDef * CANx)
-{
-    CANx->IE &= ~(1 << CAN_IE_RXOV_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTRXOverflowClear()
-* 功能说明: RX FIFO 溢出中断清除
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTRXOverflowClear(CAN_TypeDef * CANx)
+void CAN_INTClr(CAN_TypeDef * CANx, uint32_t it)
 {
     CANx->CMD = (1 << CAN_CMD_CLROV_Pos);
 }
 
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTWakeupEn()
-* 功能说明: 唤醒事件触发中断使能
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTWakeupEn(CAN_TypeDef * CANx)
-{
-    CANx->IE |= (1 << CAN_IE_WKUP_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTWakeupDis()
-* 功能说明: 唤醒事件触发中断禁止
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTWakeupDis(CAN_TypeDef * CANx)
-{
-    CANx->IE &= ~(1 << CAN_IE_WKUP_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTErrPassiveEn()
-* 功能说明: TXERR/RXERR计数值达到127时中断使能
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTErrPassiveEn(CAN_TypeDef * CANx)
-{
-    CANx->IE |= (1 << CAN_IE_ERRPASS_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTErrPassiveDis()
-* 功能说明: TXERR/RXERR计数值达到127时中断禁止
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTErrPassiveDis(CAN_TypeDef * CANx)
-{
-    CANx->IE &= ~(1 << CAN_IE_ERRPASS_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTArbitrLostEn()
-* 功能说明: 仲裁失败中断使能
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTArbitrLostEn(CAN_TypeDef * CANx)
-{
-    CANx->IE |= (1 << CAN_IE_ARBLOST_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTArbitrLostDis()
-* 功能说明: 仲裁失败中断禁止
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTArbitrLostDis(CAN_TypeDef * CANx)
-{
-    CANx->IE &= ~(1 << CAN_IE_ARBLOST_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTBusErrorEn()
-* 功能说明: 总线错误中断使能
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTBusErrorEn(CAN_TypeDef * CANx)
-{
-    CANx->IE |= (1 << CAN_IE_BUSERR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: CAN_INTBusErrorDis()
-* 功能说明: 总线错误中断禁止
-* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void CAN_INTBusErrorDis(CAN_TypeDef * CANx)
-{
-    CANx->IE &= ~(1 << CAN_IE_BUSERR_Pos);
-}
-
 /******************************************************************************************************************************************
 * 函数名称: CAN_INTStat()
 * 功能说明: 查询中断状态

+ 15 - 25
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.h

@@ -78,6 +78,18 @@ typedef struct {
 } CAN_RXMessage;
 
 
+/* Interrupt Type */
+#define CAN_IT_RX_NOTEMPTY  (0x01 << 0)     //RX Buffer Not Empty
+#define CAN_IT_RX_OVERFLOW  (0x01 << 3)     //RX Buffer Overflow
+#define CAN_IT_TX_EMPTY     (0x01 << 1)     //TX Buffer Empty
+#define CAN_IT_ARBLOST      (0x01 << 6)     //Arbitration lost
+#define CAN_IT_ERR          (0x01 << 7)
+#define CAN_IT_ERR_WARN     (0x01 << 2)     //TXERR/RXERR计数值达到Error Warning Limit
+#define CAN_IT_ERR_PASS     (0x01 << 5)     //TXERR/RXERR计数值达到127
+#define CAN_IT_WAKEUP       (0x01 << 4)
+
+
+
 void CAN_Init(CAN_TypeDef * CANx, CAN_InitStructure * initStruct);
 void CAN_Open(CAN_TypeDef * CANx);
 void CAN_Close(CAN_TypeDef * CANx);
@@ -100,31 +112,9 @@ void CAN_SetFilter32b(CAN_TypeDef * CANx, uint32_t check, uint32_t mask);
 void CAN_SetFilter16b(CAN_TypeDef * CANx, uint16_t check1, uint16_t mask1, uint16_t check2, uint16_t mask2);
 
 
-void CAN_INTRXNotEmptyEn(CAN_TypeDef * CANx);
-void CAN_INTRXNotEmptyDis(CAN_TypeDef * CANx);
-
-void CAN_INTTXBufEmptyEn(CAN_TypeDef * CANx);
-void CAN_INTTXBufEmptyDis(CAN_TypeDef * CANx);
-
-void CAN_INTErrWarningEn(CAN_TypeDef * CANx);
-void CAN_INTErrWarningDis(CAN_TypeDef * CANx);
-
-void CAN_INTRXOverflowEn(CAN_TypeDef * CANx);
-void CAN_INTRXOverflowDis(CAN_TypeDef * CANx);
-void CAN_INTRXOverflowClear(CAN_TypeDef * CANx);
-
-void CAN_INTWakeupEn(CAN_TypeDef * CANx);
-void CAN_INTWakeupDis(CAN_TypeDef * CANx);
-
-void CAN_INTErrPassiveEn(CAN_TypeDef * CANx);
-void CAN_INTErrPassiveDis(CAN_TypeDef * CANx);
-
-void CAN_INTArbitrLostEn(CAN_TypeDef * CANx);
-void CAN_INTArbitrLostDis(CAN_TypeDef * CANx);
-
-void CAN_INTBusErrorEn(CAN_TypeDef * CANx);
-void CAN_INTBusErrorDis(CAN_TypeDef * CANx);
-
+void CAN_INTEn(CAN_TypeDef * CANx, uint32_t it);
+void CAN_INTDis(CAN_TypeDef * CANx, uint32_t it);
+void CAN_INTClr(CAN_TypeDef * CANx, uint32_t it);
 uint32_t CAN_INTStat(CAN_TypeDef * CANx);
 
 #endif //__SWM320_CAN_H__

+ 3 - 42
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.c

@@ -163,7 +163,7 @@ void GPIO_Init(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t dir, uint32_t pull_up,
 ******************************************************************************************************************************************/
 void GPIO_SetBit(GPIO_TypeDef * GPIOx, uint32_t n)
 {
-    GPIOx->DATA |= (0x01 << n);
+    *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 1;
 }
 
 /******************************************************************************************************************************************
@@ -176,7 +176,7 @@ void GPIO_SetBit(GPIO_TypeDef * GPIOx, uint32_t n)
 ******************************************************************************************************************************************/
 void GPIO_ClrBit(GPIO_TypeDef * GPIOx, uint32_t n)
 {
-    GPIOx->DATA &= ~(0x01 << n);
+    *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 0;
 }
 
 /******************************************************************************************************************************************
@@ -189,7 +189,7 @@ void GPIO_ClrBit(GPIO_TypeDef * GPIOx, uint32_t n)
 ******************************************************************************************************************************************/
 void GPIO_InvBit(GPIO_TypeDef * GPIOx, uint32_t n)
 {
-    GPIOx->DATA ^= (0x01 << n);
+    *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 1 - *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4));
 }
 
 /******************************************************************************************************************************************
@@ -278,45 +278,6 @@ uint32_t GPIO_GetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
     return ((GPIOx->DATA >> n) & bits);
 }
 
-/******************************************************************************************************************************************
-* 函数名称: GPIO_AtomicSetBit()
-* 功能说明: 将参数指定的引脚电平置高,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
-* 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD
-*           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
-* 输    出: 无
-* 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
-******************************************************************************************************************************************/
-void GPIO_AtomicSetBit(GPIO_TypeDef * GPIOx, uint32_t n)
-{
-    *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 1;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: GPIO_AtomicClrBit()
-* 功能说明: 将参数指定的引脚电平置低,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
-* 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD
-*           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
-* 输    出: 无
-* 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
-******************************************************************************************************************************************/
-void GPIO_AtomicClrBit(GPIO_TypeDef * GPIOx, uint32_t n)
-{
-    *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: GPIO_AtomicInvBit()
-* 功能说明: 将参数指定的引脚电平反转,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
-* 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD
-*           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
-* 输    出: 无
-* 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
-******************************************************************************************************************************************/
-void GPIO_AtomicInvBit(GPIO_TypeDef * GPIOx, uint32_t n)
-{
-    *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 1 - *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4));
-}
-
 /******************************************************************************************************************************************
 * 函数名称: GPIO_AtomicSetBits()
 * 功能说明: 将参数指定的从n开始的w位连续引脚的电平置高,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)

+ 15 - 3
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.h

@@ -4,6 +4,14 @@
 
 void GPIO_Init(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t dir, uint32_t pull_up, uint32_t pull_down);   //引脚初始化,包含引脚方向、上拉电阻、下拉电阻
 
+#define GPIO_INPUT                      ((0 << 0) | (0 << 1) | (0 << 2))
+#define GPIO_INPUT_PullUp               ((0 << 0) | (1 << 1) | (0 << 2))
+#define GPIO_INPUT_PullDown             ((0 << 0) | (0 << 1) | (1 << 2))
+#define GPIO_OUTPUT                     ((1 << 0) | (0 << 1) | (0 << 2))
+
+#define GPIO_INIT(GPIOx, n, mode)  GPIO_Init(GPIOx, n, (mode & 1) ? 1 : 0, (mode & 2) ? 1 : 0, (mode & 4) ? 1 : 0)
+
+
 void GPIO_SetBit(GPIO_TypeDef * GPIOx, uint32_t n);                     //将参数指定的引脚电平置高
 void GPIO_ClrBit(GPIO_TypeDef * GPIOx, uint32_t n);                     //将参数指定的引脚电平置低
 void GPIO_InvBit(GPIO_TypeDef * GPIOx, uint32_t n);                     //将参数指定的引脚电平反转
@@ -13,12 +21,16 @@ void GPIO_ClrBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);        //将参
 void GPIO_InvBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);        //将参数指定的从n开始的w位连续引脚的电平反转
 uint32_t GPIO_GetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);    //读取参数指定的从n开始的w位连续引脚的电平状态
 
-void GPIO_AtomicSetBit(GPIO_TypeDef * GPIOx, uint32_t n);
-void GPIO_AtomicClrBit(GPIO_TypeDef * GPIOx, uint32_t n);
-void GPIO_AtomicInvBit(GPIO_TypeDef * GPIOx, uint32_t n);
+
 void GPIO_AtomicSetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);
 void GPIO_AtomicClrBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);
 void GPIO_AtomicInvBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);
 
 
+// for compatibility
+#define GPIO_AtomicSetBit   GPIO_SetBit
+#define GPIO_AtomicClrBit   GPIO_ClrBit
+#define GPIO_AtomicInvBit   GPIO_InvBit
+
+
 #endif //__SWM320_GPIO_H__

+ 20 - 208
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.c

@@ -173,241 +173,53 @@ static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date)
 }
 
 /******************************************************************************************************************************************
-* 函数名称: RTC_IntSecondEn()
-* 功能说明: 中断使能
+* 函数名称: RTC_INTEn()
+* 功能说明: 中断使能
 * 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
+*           uint32_t it             interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void RTC_IntSecondEn(RTC_TypeDef * RTCx)
+void RTC_INTEn(RTC_TypeDef * RTCx, uint32_t it)
 {
-    RTCx->IE |= (1 << RTC_IE_SEC_Pos);
+    RTCx->IE |= it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: RTC_IntSecondDis()
-* 功能说明: 中断禁止
+* 函数名称: RTC_INTDis()
+* 功能说明: 中断禁止
 * 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
+*           uint32_t it             interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void RTC_IntSecondDis(RTC_TypeDef * RTCx)
+void RTC_INTDis(RTC_TypeDef * RTCx, uint32_t it)
 {
-    RTCx->IE &= ~(1 << RTC_IE_SEC_Pos);
+    RTCx->IE &= ~it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: RTC_IntSecondClr()
-* 功能说明: 中断标志清除
+* 函数名称: RTC_INTClr()
+* 功能说明: 中断标志清除
 * 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
+*           uint32_t it             interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void RTC_IntSecondClr(RTC_TypeDef * RTCx)
+void RTC_INTClr(RTC_TypeDef * RTCx, uint32_t it)
 {
-    RTCx->IF = (1 << RTC_IF_SEC_Pos);
+    RTCx->IF = it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: RTC_IntSecondStat()
-* 功能说明: 中断状态
+* 函数名称: RTC_INTStat()
+* 功能说明: 中断状态
 * 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
+*           uint32_t it             interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM
 * 输    出: uint32_t              1 秒中断发生    0 秒中断未发生
 * 注意事项: 无
 ******************************************************************************************************************************************/
-uint32_t RTC_IntSecondStat(RTC_TypeDef * RTCx)
+uint32_t RTC_INTStat(RTC_TypeDef * RTCx, uint32_t it)
 {
-    return (RTCx->IF & RTC_IF_SEC_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntMinuteEn()
-* 功能说明: 分中断使能
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntMinuteEn(RTC_TypeDef * RTCx)
-{
-    RTCx->IE |= (1 << RTC_IE_MIN_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntMinuteDis()
-* 功能说明: 分中断禁止
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntMinuteDis(RTC_TypeDef * RTCx)
-{
-    RTCx->IE &= ~(1 << RTC_IE_MIN_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntMinuteClr()
-* 功能说明: 分中断标志清除
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntMinuteClr(RTC_TypeDef * RTCx)
-{
-    RTCx->IF = (1 << RTC_IF_MIN_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntMinuteStat()
-* 功能说明: 分中断状态
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: uint32_t              1 分中断发生    0 分中断未发生
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t RTC_IntMinuteStat(RTC_TypeDef * RTCx)
-{
-    return (RTCx->IF & RTC_IF_MIN_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntHourEn()
-* 功能说明: 时中断使能
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntHourEn(RTC_TypeDef * RTCx)
-{
-    RTCx->IE |= (1 << RTC_IE_HOUR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntHourDis()
-* 功能说明: 时中断禁止
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntHourDis(RTC_TypeDef * RTCx)
-{
-    RTCx->IE &= ~(1 << RTC_IE_HOUR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntHourClr()
-* 功能说明: 时中断标志清除
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntHourClr(RTC_TypeDef * RTCx)
-{
-    RTCx->IF = (1 << RTC_IF_HOUR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntHourStat()
-* 功能说明: 时中断状态
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: uint32_t              1 时中断发生    0 时中断未发生
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t RTC_IntHourStat(RTC_TypeDef * RTCx)
-{
-    return (RTCx->IF & RTC_IF_HOUR_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntDateEn()
-* 功能说明: 日中断使能
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntDateEn(RTC_TypeDef * RTCx)
-{
-    RTCx->IE |= (1 << RTC_IE_DATE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntDateDis()
-* 功能说明: 日中断禁止
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntDateDis(RTC_TypeDef * RTCx)
-{
-    RTCx->IE &= ~(1 << RTC_IE_DATE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntDateClr()
-* 功能说明: 日中断标志清除
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntDateClr(RTC_TypeDef * RTCx)
-{
-    RTCx->IF = (1 << RTC_IF_DATE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntDateStat()
-* 功能说明: 日中断状态
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: uint32_t              1 日中断发生    0 日中断未发生
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t RTC_IntDateStat(RTC_TypeDef * RTCx)
-{
-    return (RTCx->IF & RTC_IF_DATE_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntAlarmEn()
-* 功能说明: 闹钟中断使能
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntAlarmEn(RTC_TypeDef * RTCx)
-{
-    RTCx->IE |= (1 << RTC_IE_ALARM_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntAlarmDis()
-* 功能说明: 闹钟中断禁止
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntAlarmDis(RTC_TypeDef * RTCx)
-{
-    RTCx->IE &= ~(1 << RTC_IE_ALARM_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntAlarmClr()
-* 功能说明: 闹钟中断标志清除
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntAlarmClr(RTC_TypeDef * RTCx)
-{
-    RTCx->IF = (1 << RTC_IF_ALARM_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntAlarmStat()
-* 功能说明: 闹钟中断状态
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: uint32_t              1 闹钟中断发生    0 闹钟中断未发生
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t RTC_IntAlarmStat(RTC_TypeDef * RTCx)
-{
-    return (RTCx->IF & RTC_IF_ALARM_Msk) ? 1 : 0;
+    return (RTCx->IF & it) ? 1 : 0;
 }

+ 13 - 20
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.h

@@ -40,6 +40,15 @@ typedef struct {
     uint8_t  Second;
 } RTC_DateTime;
 
+
+/* Interrupt Type */
+#define RTC_IT_SECOND       (1 << 0)    //Second Interrupt
+#define RTC_IT_MINUTE       (1 << 1)
+#define RTC_IT_HOUR         (1 << 2)
+#define RTC_IT_DATE         (1 << 3)
+#define RTC_IT_ALARM        (1 << 4)
+
+
 void RTC_Init(RTC_TypeDef * RTCx, RTC_InitStructure * initStruct);
 void RTC_Start(RTC_TypeDef * RTCx);
 void RTC_Stop(RTC_TypeDef * RTCx);
@@ -49,25 +58,9 @@ void RTC_GetDateTime(RTC_TypeDef * RTCx, RTC_DateTime * dateTime);
 void RTC_AlarmSetup(RTC_TypeDef * RTCx, RTC_AlarmStructure * alarmStruct);
 
 
-void RTC_IntSecondEn(RTC_TypeDef * RTCx);
-void RTC_IntSecondDis(RTC_TypeDef * RTCx);
-void RTC_IntSecondClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntSecondStat(RTC_TypeDef * RTCx);
-void RTC_IntMinuteEn(RTC_TypeDef * RTCx);
-void RTC_IntMinuteDis(RTC_TypeDef * RTCx);
-void RTC_IntMinuteClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntMinuteStat(RTC_TypeDef * RTCx);
-void RTC_IntHourEn(RTC_TypeDef * RTCx);
-void RTC_IntHourDis(RTC_TypeDef * RTCx);
-void RTC_IntHourClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntHourStat(RTC_TypeDef * RTCx);
-void RTC_IntDateEn(RTC_TypeDef * RTCx);
-void RTC_IntDateDis(RTC_TypeDef * RTCx);
-void RTC_IntDateClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntDateStat(RTC_TypeDef * RTCx);
-void RTC_IntAlarmEn(RTC_TypeDef * RTCx);
-void RTC_IntAlarmDis(RTC_TypeDef * RTCx);
-void RTC_IntAlarmClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntAlarmStat(RTC_TypeDef * RTCx);
+void RTC_INTEn(RTC_TypeDef * RTCx, uint32_t it);
+void RTC_INTDis(RTC_TypeDef * RTCx, uint32_t it);
+void RTC_INTClr(RTC_TypeDef * RTCx, uint32_t it);
+uint32_t RTC_INTStat(RTC_TypeDef * RTCx, uint32_t it);
 
 #endif //__SWM320_RTC_H__

+ 5 - 0
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdio.c

@@ -33,6 +33,7 @@ SD_CardInfo SD_cardInfo;
 ******************************************************************************************************************************************/
 uint32_t SDIO_Init(uint32_t freq)
 {
+    uint32_t i;
     uint32_t res;
     uint32_t resp, resps[4];
 
@@ -59,6 +60,8 @@ uint32_t SDIO_Init(uint32_t freq)
 
     while((SDIO->CR2 & SDIO_CR2_CLKRDY_Msk) == 0);
 
+    for(i = 0; i < CyclesPerUs * 10 ; i++) __NOP();
+
     SDIO->IM = 0xFFFFFFFF;
 
 
@@ -122,6 +125,8 @@ uint32_t SDIO_Init(uint32_t freq)
 
     SDIO_SendCmd(SD_CMD_SET_BLOCKLEN, 512, SD_RESP_32b, &resp);     //固定块大小位512字节
 
+    SD_cardInfo.CardBlockSize = 512;
+
     SDIO->BLK = 512;
 
     return SD_RES_OK;

+ 2 - 2
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.c

@@ -42,7 +42,7 @@ void SDRAM_Init(SDRAM_InitStructure * initStruct)
 
     SDRAMC->CR1 = (initStruct->CellSize << SDRAMC_CR1_CELLSIZE_Pos) |
                   (initStruct->CellWidth << SDRAMC_CR1_CELL32BIT_Pos) |
-                  (initStruct->CellBank << SDRAMC_CR1_BANK_Pos) |
+                  ((initStruct->CellSize == SDRAM_CELLSIZE_16Mb ? SDRAM_CELLBANK_2 : SDRAM_CELLBANK_4) << SDRAMC_CR1_BANK_Pos) |
                   (0 << SDRAMC_CR1_32BIT_Pos) |
                   (initStruct->TimeTMRD << SDRAMC_CR1_TMRD_Pos) |
                   (initStruct->TimeTRRD << SDRAMC_CR1_TRRD_Pos) |
@@ -63,7 +63,7 @@ void SDRAM_Init(SDRAM_InitStructure * initStruct)
     }
 
     SDRAMC->REFRESH = (1 << SDRAMC_REFRESH_EN_Pos) |
-                      (((SystemCoreClock/2)/1000*64 / (1 << row_n)) << SDRAMC_REFRESH_RATE_Pos);
+                      (((SystemCoreClock/2)/1000 * initStruct->RefreshTime / (1 << row_n)) << SDRAMC_REFRESH_RATE_Pos);
 
     while(SDRAMC->REFDONE == 0);
 }

+ 3 - 2
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.h

@@ -3,14 +3,15 @@
 
 typedef struct {
     uint8_t CellSize;           // SDRAM颗粒的容量,SDRAM_CELLSIZE_16Mb、SDRAM_CELLSIZE_64Mb、SDRAM_CELLSIZE_128Mb、SDRAM_CELLSIZE_256Mb
-    uint8_t CellBank;           // SDRAM颗粒有几个bank,SDRAM_CELLBANK_2、SDRAM_CELLBANK_4
     uint8_t CellWidth;          // SDRAM颗粒的位宽,SDRAM_CELLWIDTH_16、SDRAM_CELLWIDTH_32
     uint8_t CASLatency;         // 列地址到有效数据输出间隔,SDRAM_CASLATENCY_2、SDRAM_CASLATENCY_3
+    uint8_t RefreshTime;        // 刷新时间,单位 ms,在这个时间内 SDRAM 必须完成一次整片刷新,通常为 64ms
 
     uint8_t TimeTMRD;           // MRS to New Command
     uint8_t TimeTRRD;           // Activate to activate on different banks
     uint8_t TimeTRAS;           // Self refresh time,最小Self-refresh周期
-    uint8_t TimeTRC;            // Row cycle delay,Refresh命令到Activate命令间延时,也是两个连续Refresh命令间延时
+    uint8_t TimeTRC;            // Row cycle delay,Activate to activate on same bank
+                                // 若 SDRAM 颗粒除了 tRC,还有 tRFC 或 tRRC 参数,则按照二者中较大的计算 TimeTRC
     uint8_t TimeTRCD;           // Row to column delay,行地址到列地址间延时,也即Activate命令到读写命令间延时
     uint8_t TimeTRP;            // Row precharge delay,Precharge命令到另一个命令间延时
 } SDRAM_InitStructure;

+ 26 - 307
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.c

@@ -58,7 +58,7 @@ void SPI_Init(SPI_TypeDef * SPIx, SPI_InitStructure * initStruct)
     SPIx->IF = (0x01 << SPI_IF_RFOVF_Pos);  //清除中断标志
     SPIx->IE &= ~(SPI_IE_RFHF_Msk | SPI_IE_TFHF_Msk | SPI_IE_FTC_Msk);
     SPIx->IE |= (initStruct->RXHFullIEn << SPI_IE_RFHF_Pos) |
-                (initStruct->TXEmptyIEn << SPI_IE_TFHF_Pos) |
+                (initStruct->TXEmptyIEn << SPI_IE_TFE_Pos) |
                 (initStruct->TXCompleteIEn << SPI_IE_FTC_Pos);
 
     switch((uint32_t)SPIx)
@@ -205,339 +205,58 @@ uint32_t SPI_IsTXEmpty(SPI_TypeDef * SPIx)
     return (SPIx->STAT & SPI_STAT_TFE_Msk) ? 1 : 0;
 }
 
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXHalfFullEn()
-* 功能说明: 接收FIFO半满中断使能
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXHalfFullEn(SPI_TypeDef * SPIx)
-{
-    SPIx->IE |= (0x01 << SPI_IE_RFHF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXHalfFullDis()
-* 功能说明: 接收FIFO半满中断禁止
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXHalfFullDis(SPI_TypeDef * SPIx)
-{
-    SPIx->IE &= ~(0x01 << SPI_IE_RFHF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXHalfFullClr()
-* 功能说明: 接收FIFO半满中断标志清除
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXHalfFullClr(SPI_TypeDef * SPIx)
-{
-    SPIx->IF = (1 << SPI_IF_RFHF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXHalfFullStat()
-* 功能说明: 接收FIFO半满中断状态
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: uint32_t              1 接收FIFO达到半满    0 接收FIFO未达到半满
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t SPI_INTRXHalfFullStat(SPI_TypeDef * SPIx)
-{
-    return (SPIx->IF & SPI_IF_RFHF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXFullEn()
-* 功能说明: 接收FIFO满中断使能
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXFullEn(SPI_TypeDef * SPIx)
-{
-    SPIx->IE |= (0x01 << SPI_IE_RFF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXFullDis()
-* 功能说明: 接收FIFO满中断禁止
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXFullDis(SPI_TypeDef * SPIx)
-{
-    SPIx->IE &= ~(0x01 << SPI_IE_RFF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXFullClr()
-* 功能说明: 接收FIFO满中断标志清除
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXFullClr(SPI_TypeDef * SPIx)
-{
-    SPIx->IF = (1 << SPI_IF_RFF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXFullStat()
-* 功能说明: 接收FIFO满中断状态
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: uint32_t              1 接收FIFO满    0 接收FIFO未满
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t SPI_INTRXFullStat(SPI_TypeDef * SPIx)
-{
-    return (SPIx->IF & SPI_IF_RFF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXOverflowEn()
-* 功能说明: 接收FIFO溢出中断使能
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXOverflowEn(SPI_TypeDef * SPIx)
-{
-    SPIx->IE |= (0x01 << SPI_IE_RFOVF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXOverflowDis()
-* 功能说明: 接收FIFO溢出中断禁止
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXOverflowDis(SPI_TypeDef * SPIx)
-{
-    SPIx->IE &= ~(0x01 << SPI_IE_RFOVF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXOverflowClr()
-* 功能说明: 接收FIFO溢出中断标志清除
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTRXOverflowClr(SPI_TypeDef * SPIx)
-{
-    SPIx->IF = (0x01 << SPI_IF_RFOVF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTRXOverflowStat()
-* 功能说明: 接收FIFO溢出中断状态
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: uint32_t              1 接收FIFO溢出    0 接收FIFO未溢出
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t SPI_INTRXOverflowStat(SPI_TypeDef * SPIx)
-{
-    return (SPIx->IF & SPI_IF_RFOVF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXHalfFullEn()
-* 功能说明: 发送FIFO半满中断使能
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXHalfFullEn(SPI_TypeDef * SPIx)
-{
-    SPIx->IE |= (0x01 << SPI_IE_TFHF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXHalfFullDis()
-* 功能说明: 发送FIFO半满中断禁止
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXHalfFullDis(SPI_TypeDef * SPIx)
-{
-    SPIx->IE &= ~(0x01 << SPI_IE_TFHF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXHalfFullClr()
-* 功能说明: 发送FIFO半满中断标志清除
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXHalfFullClr(SPI_TypeDef * SPIx)
-{
-    SPIx->IF = (1 << SPI_IF_TFHF_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXHalfFullStat()
-* 功能说明: 发送FIFO半满中断状态
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: uint32_t              1 发送FIFO达到半满    0 发送FIFO未达到半满
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t SPI_INTTXHalfFullStat(SPI_TypeDef * SPIx)
-{
-    return (SPIx->IF & SPI_IF_TFHF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXEmptyEn()
-* 功能说明: 发送FIFO空中断使能
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXEmptyEn(SPI_TypeDef * SPIx)
-{
-    SPIx->IE |= (0x01 << SPI_IE_TFE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXEmptyDis()
-* 功能说明: 发送FIFO空中断禁止
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXEmptyDis(SPI_TypeDef * SPIx)
-{
-    SPIx->IE &= ~(0x01 << SPI_IE_TFE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXEmptyClr()
-* 功能说明: 发送FIFO空中断标志清除
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXEmptyClr(SPI_TypeDef * SPIx)
-{
-    SPIx->IF = (1 << SPI_IF_TFE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXEmptyStat()
-* 功能说明: 发送FIFO空中断状态
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: uint32_t              1 发送FIFO空    0 发送FIFO非空
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t SPI_INTTXEmptyStat(SPI_TypeDef * SPIx)
-{
-    return (SPIx->IF & SPI_IF_TFE_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXCompleteEn()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断使能
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXCompleteEn(SPI_TypeDef * SPIx)
-{
-    SPIx->IE |= (0x01 << SPI_IE_FTC_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXCompleteDis()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断禁止
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXCompleteDis(SPI_TypeDef * SPIx)
-{
-    SPIx->IE &= ~(0x01 << SPI_IE_FTC_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXCompleteClr()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断状态清除
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void SPI_INTTXCompleteClr(SPI_TypeDef * SPIx)
-{
-    SPIx->IF = (1 << SPI_IF_FTC_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: SPI_INTTXCompleteStat()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断状态
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: uint32_t              1 发送FIFO空且发送移位寄存器空    0 发送FIFO或发送移位寄存器非空
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t SPI_INTTXCompleteStat(SPI_TypeDef * SPIx)
-{
-    return (SPIx->IF & SPI_IF_FTC_Msk) ? 1 : 0;
-}
-
 /******************************************************************************************************************************************
-* 函数名称: SPI_INTTXWordCompleteEn()
-* 功能说明: 发送FIFO字发送完成中断使能
+* 函数名称: SPI_INTEn()
+* 功能说明: 中断使能
 * 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
+*           uint32_t it             interrupt type,有效值SPI_IT_RX_OVF、SPI_IT_RX_FULL、SPI_IT_RX_HFULL、SPI_IT_TX_EMPTY、SPI_IT_TX_HFULL、
+*                                   SPI_IT_TX_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void SPI_INTTXWordCompleteEn(SPI_TypeDef * SPIx)
+void SPI_INTEn(SPI_TypeDef * SPIx, uint32_t it)
 {
-    SPIx->IE |= (0x01 << SPI_IE_WTC_Pos);
+    SPIx->IE |= it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: SPI_INTTXWordCompleteDis()
-* 功能说明: 发送FIFO字发送完成中断禁止
+* 函数名称: SPI_INTDis()
+* 功能说明: 中断禁止
 * 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
+*           uint32_t it             interrupt type,有效值SPI_IT_RX_OVF、SPI_IT_RX_FULL、SPI_IT_RX_HFULL、SPI_IT_TX_EMPTY、SPI_IT_TX_HFULL、
+*                                   SPI_IT_TX_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void SPI_INTTXWordCompleteDis(SPI_TypeDef * SPIx)
+void SPI_INTDis(SPI_TypeDef * SPIx, uint32_t it)
 {
-    SPIx->IE &= ~(0x01 << SPI_IE_WTC_Pos);
+    SPIx->IE &= ~it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: SPI_INTTXWordCompleteClr()
-* 功能说明: 发送FIFO字发送完成中断标志清除
+* 函数名称: SPI_INTClr()
+* 功能说明: 中断标志清除
 * 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
+*           uint32_t it             interrupt type,有效值SPI_IT_RX_OVF、SPI_IT_RX_FULL、SPI_IT_RX_HFULL、SPI_IT_TX_EMPTY、SPI_IT_TX_HFULL、
+*                                   SPI_IT_TX_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void SPI_INTTXWordCompleteClr(SPI_TypeDef * SPIx)
+void SPI_INTClr(SPI_TypeDef * SPIx, uint32_t it)
 {
-    SPIx->IF = (1 << SPI_IF_WTC_Pos);
+    SPIx->IF = it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: SPI_INTTXWordCompleteStat()
-* 功能说明: 发送FIFO字发送完成中断状态
+* 函数名称: SPI_INTStat()
+* 功能说明: 中断状态查询
 * 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-* 输    出: uint32_t              1 发送完成中断已发生    0 发送完成中断未发生
+*           uint32_t it             interrupt type,有效值SPI_IT_RX_OVF、SPI_IT_RX_FULL、SPI_IT_RX_HFULL、SPI_IT_TX_EMPTY、SPI_IT_TX_HFULL、
+*                                   SPI_IT_TX_DONE 及其“或”
+* 输    出: uint32_t              1 中断发生    0 中断未发生
 * 注意事项: 无
 ******************************************************************************************************************************************/
-uint32_t SPI_INTTXWordCompleteStat(SPI_TypeDef * SPIx)
+uint32_t SPI_INTStat(SPI_TypeDef * SPIx, uint32_t it)
 {
-    return (SPIx->IF & SPI_IF_WTC_Msk) ? 1 : 0;
+    return (SPIx->IF & it) ? 1 : 0;
 }

+ 13 - 30
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.h

@@ -33,6 +33,15 @@ typedef struct {
 #define SPI_CLKDIV_512          7
 
 
+/* Interrupt Type */
+#define SPI_IT_RX_OVF       (1 << 0)    //RX FIFO Overflow
+#define SPI_IT_RX_FULL      (1 << 1)    //RX FIFO Full
+#define SPI_IT_RX_HFULL     (1 << 2)    //RX FIFO Half Full
+#define SPI_IT_TX_EMPTY     (1 << 3)    //TX FIFO Empty
+#define SPI_IT_TX_HFULL     (1 << 4)    //TX FIFO Half Full
+#define SPI_IT_TX_DONE      (1 << 9)    //TX Done(发送FIFO空且发送移位寄存器空)
+
+
 
 void SPI_Init(SPI_TypeDef * SPIx, SPI_InitStructure * initStruct);      //SPI初始化
 void SPI_Open(SPI_TypeDef * SPIx);                                      //SPI打开,允许收发
@@ -48,36 +57,10 @@ uint32_t SPI_IsTXFull(SPI_TypeDef * SPIx);              //发送FIFO是否满,
 uint32_t SPI_IsTXEmpty(SPI_TypeDef * SPIx);             //发送FIFO是否空
 
 
-void SPI_INTRXHalfFullEn(SPI_TypeDef * SPIx);
-void SPI_INTRXHalfFullDis(SPI_TypeDef * SPIx);
-void SPI_INTRXHalfFullClr(SPI_TypeDef * SPIx);
-uint32_t SPI_INTRXHalfFullStat(SPI_TypeDef * SPIx);
-void SPI_INTRXFullEn(SPI_TypeDef * SPIx);
-void SPI_INTRXFullDis(SPI_TypeDef * SPIx);
-void SPI_INTRXFullClr(SPI_TypeDef * SPIx);
-uint32_t SPI_INTRXFullStat(SPI_TypeDef * SPIx);
-void SPI_INTRXOverflowEn(SPI_TypeDef * SPIx);
-void SPI_INTRXOverflowDis(SPI_TypeDef * SPIx);
-void SPI_INTRXOverflowClr(SPI_TypeDef * SPIx);
-uint32_t SPI_INTRXOverflowStat(SPI_TypeDef * SPIx);
-
-void SPI_INTTXHalfFullEn(SPI_TypeDef * SPIx);
-void SPI_INTTXHalfFullDis(SPI_TypeDef * SPIx);
-void SPI_INTTXHalfFullClr(SPI_TypeDef * SPIx);
-uint32_t SPI_INTTXHalfFullStat(SPI_TypeDef * SPIx);
-void SPI_INTTXEmptyEn(SPI_TypeDef * SPIx);
-void SPI_INTTXEmptyDis(SPI_TypeDef * SPIx);
-void SPI_INTTXEmptyClr(SPI_TypeDef * SPIx);
-uint32_t SPI_INTTXEmptyStat(SPI_TypeDef * SPIx);
-void SPI_INTTXCompleteEn(SPI_TypeDef * SPIx);
-void SPI_INTTXCompleteDis(SPI_TypeDef * SPIx);
-void SPI_INTTXCompleteClr(SPI_TypeDef * SPIx);
-uint32_t SPI_INTTXCompleteStat(SPI_TypeDef * SPIx);
-
-void SPI_INTTXWordCompleteEn(SPI_TypeDef * SPIx);
-void SPI_INTTXWordCompleteDis(SPI_TypeDef * SPIx);
-void SPI_INTTXWordCompleteClr(SPI_TypeDef * SPIx);
-uint32_t SPI_INTTXWordCompleteStat(SPI_TypeDef * SPIx);
+void SPI_INTEn(SPI_TypeDef * SPIx, uint32_t it);        //中断使能
+void SPI_INTDis(SPI_TypeDef * SPIx, uint32_t it);       //中断禁止
+void SPI_INTClr(SPI_TypeDef * SPIx, uint32_t it);       //中断标志清除
+uint32_t SPI_INTStat(SPI_TypeDef * SPIx, uint32_t it);  //中断状态查询
 
 
 #endif //__SWM320_SPI_H__

+ 20 - 122
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.c

@@ -372,7 +372,7 @@ uint32_t UART_LINIsGenerated(UART_TypeDef * UARTx)
 ******************************************************************************************************************************************/
 void UART_ABRStart(UART_TypeDef * UARTx, uint32_t detectChar)
 {
-    uint32_t bits;
+    uint32_t bits = 0;
 
     if((detectChar == 0xFF) || (detectChar == 0x1FF))      bits = 0;
     else if((detectChar == 0xFE) || (detectChar == 0x1FE)) bits = 1;
@@ -409,145 +409,43 @@ uint32_t UART_ABRIsDone(UART_TypeDef * UARTx)
 }
 
 /******************************************************************************************************************************************
-* 函数名称: UART_INTRXThresholdEn()
-* 功能说明: 当RX FIFO中数据个数 >= RXThreshold时 触发中断
+* 函数名称: UART_INTEn()
+* 功能说明: 中断使能
 * 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
+*           uint32_t it             interrupt type,有效值有 UART_IT_RX_THR、UART_IT_RX_TOUT、UART_IT_TX_THR、UART_IT_TX_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void UART_INTRXThresholdEn(UART_TypeDef * UARTx)
+void UART_INTEn(UART_TypeDef * UARTx, uint32_t it)
 {
-    UARTx->CTRL |= (0x01 << UART_CTRL_RXIE_Pos);
+    UARTx->CTRL |= it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: UART_INTRXThresholdDis()
-* 功能说明: 当RX FIFO中数据个数 >= RXThreshold时 不触发中断
+* 函数名称: UART_INTDis()
+* 功能说明: 中断禁止
 * 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
+*           uint32_t it             interrupt type,有效值有 UART_IT_RX_THR、UART_IT_RX_TOUT、UART_IT_TX_THR、UART_IT_TX_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void UART_INTRXThresholdDis(UART_TypeDef * UARTx)
+void UART_INTDis(UART_TypeDef * UARTx, uint32_t it)
 {
-    UARTx->CTRL &= ~(0x01 << UART_CTRL_RXIE_Pos);
+    UARTx->CTRL &= ~it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: UART_INTRXThresholdStat()
-* 功能说明: 是否RX FIFO中数据个数 >= RXThreshold
+* 函数名称: UART_INTStat()
+* 功能说明: 中断状态查询
 * 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: uint32_t              1 RX FIFO中数据个数 >= RXThreshold       0 RX FIFO中数据个数 < RXThreshold
-* 注意事项: RXIF = RXTHRF & RXIE
-******************************************************************************************************************************************/
-uint32_t UART_INTRXThresholdStat(UART_TypeDef * UARTx)
-{
-    return (UARTx->BAUD & UART_BAUD_RXIF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXThresholdEn()
-* 功能说明: 当TX FIFO中数据个数 <= TXThreshold时 触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTXThresholdEn(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL |= (0x01 << UART_CTRL_TXIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXThresholdDis()
-* 功能说明: 当TX FIFO中数据个数 <= TXThreshold时 不触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTXThresholdDis(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL &= ~(0x01 << UART_CTRL_TXIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXThresholdStat()
-* 功能说明: 是否TX FIFO中数据个数 <= TXThreshold
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: uint32_t              1 TX FIFO中数据个数 <= TXThreshold       0 TX FIFO中数据个数 > TXThreshold
-* 注意事项: TXIF = TXTHRF & TXIE
-******************************************************************************************************************************************/
-uint32_t UART_INTTXThresholdStat(UART_TypeDef * UARTx)
-{
-    return (UARTx->BAUD & UART_BAUD_TXIF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTimeoutEn()
-* 功能说明: 接收发生超时时 触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTimeoutEn(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL |= (0x01 << UART_CTRL_TOIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTimeoutDis()
-* 功能说明: 接收发生超时时 不触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTimeoutDis(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL &= ~(0x01 << UART_CTRL_TOIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTimeoutStat()
-* 功能说明: 是否发生了接收超时,即超过 TimeoutTime/(Baudrate/10) 秒没有在RX线上接收到数据时触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: uint32_t              1 发生了接收超时       0 未发生接收超时
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t UART_INTTimeoutStat(UART_TypeDef * UARTx)
-{
-    return (UARTx->BAUD & UART_BAUD_TOIF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXDoneEn()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断使能
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTXDoneEn(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL |= (0x01 << UART_CTRL_TXDOIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXDoneDis()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断禁止
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTXDoneDis(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL &= ~(0x01 << UART_CTRL_TXDOIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXDoneStat()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断状态
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: uint32_t              1 发送FIFO空且发送移位寄存器空      0 发送FIFO或发送移位寄存器未空
+*           uint32_t it             interrupt type,有效值有 UART_IT_RX_THR、UART_IT_RX_TOUT、UART_IT_TX_THR、UART_IT_TX_DONE 及其“或”
+* 输    出: uint32_t              1 中断已发生    0 中断未发生
 * 注意事项: 无
 ******************************************************************************************************************************************/
-uint32_t UART_INTTXDoneStat(UART_TypeDef * UARTx)
+uint32_t UART_INTStat(UART_TypeDef * UARTx, uint32_t it)
 {
-    return (UARTx->BAUD & UART_BAUD_TXDOIF_Msk) ? 1 : 0;
+    return (((it & UART_IT_RX_THR)  && (UARTx->BAUD & UART_BAUD_RXIF_Msk)) ||
+            ((it & UART_IT_RX_TOUT) && (UARTx->BAUD & UART_BAUD_TOIF_Msk)) ||
+            ((it & UART_IT_TX_THR)  && (UARTx->BAUD & UART_BAUD_TXIF_Msk)) ||
+            ((it & UART_IT_TX_DONE) && (UARTx->BAUD & UART_BAUD_TXDOIF_Msk)));
 }

+ 11 - 13
bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.h

@@ -46,6 +46,14 @@ typedef struct {
 #define UART_ERR_NOISE      3
 
 
+/* Interrupt Type */
+#define UART_IT_RX_THR      (1 << UART_CTRL_RXIE_Pos)   //RX FIFO Threshold, RX FIFO中数据个数 >  RXThreshold
+#define UART_IT_RX_TOUT     (1 << UART_CTRL_TOIE_Pos)   //RX Timeout, 超过 TimeoutTime/(Baudrate/10) 秒没有在RX线上接收到数据
+#define UART_IT_TX_THR      (1 << UART_CTRL_TXIE_Pos)   //TX FIFO Threshold, TX FIFO中数据个数 <= TXThreshold
+#define UART_IT_TX_DONE     (1 << UART_CTRL_TXDOIE_Pos) //TX Done, 发送FIFO空且发送发送移位寄存器已将最后一位发送出去
+
+
+
 void UART_Init(UART_TypeDef * UARTx, UART_InitStructure * initStruct);  //UART串口初始化
 void UART_Open(UART_TypeDef * UARTx);
 void UART_Close(UART_TypeDef * UARTx);
@@ -76,19 +84,9 @@ void UART_ABRStart(UART_TypeDef * UARTx, uint32_t detectChar);
 uint32_t UART_ABRIsDone(UART_TypeDef * UARTx);
 
 
-void UART_INTRXThresholdEn(UART_TypeDef * UARTx);
-void UART_INTRXThresholdDis(UART_TypeDef * UARTx);
-uint32_t UART_INTRXThresholdStat(UART_TypeDef * UARTx);
-void UART_INTTXThresholdEn(UART_TypeDef * UARTx);
-void UART_INTTXThresholdDis(UART_TypeDef * UARTx);
-uint32_t UART_INTTXThresholdStat(UART_TypeDef * UARTx);
-void UART_INTTimeoutEn(UART_TypeDef * UARTx);
-void UART_INTTimeoutDis(UART_TypeDef * UARTx);
-uint32_t UART_INTTimeoutStat(UART_TypeDef * UARTx);
-
-void UART_INTTXDoneEn(UART_TypeDef * UARTx);
-void UART_INTTXDoneDis(UART_TypeDef * UARTx);
-uint32_t UART_INTTXDoneStat(UART_TypeDef * UARTx);
+void UART_INTEn(UART_TypeDef * UARTx, uint32_t it);
+void UART_INTDis(UART_TypeDef * UARTx, uint32_t it);
+uint32_t UART_INTStat(UART_TypeDef * UARTx, uint32_t it);
 
 
 #endif //__SWM320_UART_H__

+ 2 - 0
bsp/synwit/swm320/rtconfig.h

@@ -6,6 +6,7 @@
 
 /* RT-Thread Kernel */
 
+#define RT_CPUS_NR 1
 #define RT_NAME_MAX 8
 #define RT_ALIGN_SIZE 8
 #define RT_THREAD_PRIORITY_32
@@ -40,6 +41,7 @@
 #define RT_USING_MEMHEAP_AS_HEAP
 #define RT_USING_MEMHEAP_AUTO_BINDING
 #define RT_USING_HEAP
+#define RT_BACKTRACE_LEVEL_MAX_NR 32
 
 /* Kernel Device Object */
 

+ 0 - 5
bsp/synwit/swm341/README.md

@@ -144,11 +144,6 @@ msh >
 | SDIO        |     支持     | SDIO                                       |
 | SDRAM       |     支持     | SDRAM                                      |
 
-## 维护人信息
-
-- [yanmowudi](https://github.com/yanmowudi)
-- [邮箱](lik@synwit.cn)
-
 ## 参考资料
 
 * [RT-Thread 文档中心](https://www.rt-thread.org/document/site/)

+ 3 - 2
bsp/synwit/swm341/drivers/drv_sdram.c

@@ -63,9 +63,10 @@ int swm_sdram_init(void)
     SDRAM_InitStruct.Size = SDRAM_SIZE_8MB;
     SDRAM_InitStruct.ClkDiv = SDRAM_CLKDIV_1;
     SDRAM_InitStruct.CASLatency = SDRAM_CASLATENCY_3;
-    SDRAM_InitStruct.TimeTRP = SDRAM_TRP_2;
+    SDRAM_InitStruct.RefreshTime = 64;
+    SDRAM_InitStruct.TimeTRP  = SDRAM_TRP_2;
     SDRAM_InitStruct.TimeTRCD = SDRAM_TRCD_2;
-    SDRAM_InitStruct.TimeTRFC = SDRAM_TRFC_9;
+    SDRAM_InitStruct.TimeTRC  = SDRAM_TRC_7;
     SDRAM_Init(&SDRAM_InitStruct);
 
     return 0;

+ 1 - 1
bsp/synwit/swm341/drivers/drv_uart.c

@@ -273,7 +273,7 @@ static void swm_uart_isr(struct rt_serial_device *serial_device)
     uart_cfg = serial_device->parent.user_data;
 
     /* UART in mode Receiver -------------------------------------------------*/
-    if (UART_INTRXThresholdStat(uart_cfg->UARTx) || UART_INTTimeoutStat(uart_cfg->UARTx))
+    if (UART_INTStat(uart_cfg->UARTx, UART_IT_RX_THR) || UART_INTStat(uart_cfg->UARTx, UART_IT_RX_TOUT))
     {
         rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_IND);
     }

+ 77 - 23
bsp/synwit/swm341/libraries/CMSIS/DeviceSupport/SWM341.h

@@ -274,8 +274,6 @@ typedef struct {
 #define SYS_CLKSEL_SDIO_Msk         (0x03 << SYS_CLKSEL_SDIO_Pos)
 #define SYS_CLKSEL_WDT_Pos          12      //看门狗时钟选择  0 HRC   1 XTAL   2 LRC   3 XTAL_32K
 #define SYS_CLKSEL_WDT_Msk          (0x03 << SYS_CLKSEL_WDT_Pos)
-#define SYS_CLKSEL_RTCTRIM_Pos      14      //RTC Trim参考时钟  0 XTAL   1 XTAL/2   2 XTAL/4   3 XTAL/8
-#define SYS_CLKSEL_RTCTRIM_Msk      (0x03 << SYS_CLKSEL_RTCTRIM_Pos)
 #define SYS_CLKSEL_AD0_Pos          16      //ADC0时钟选择  0 HRC   1 XTAL   2 PLL
 #define SYS_CLKSEL_AD0_Msk          (0x03 << SYS_CLKSEL_AD0_Pos)
 #define SYS_CLKSEL_AD0DIV_Pos       18      //ADC0时钟分频  0 1分频   1 1分频   2 4分频   3 8分频
@@ -477,12 +475,14 @@ typedef struct {
 
 #define SYS_PRSTR1_GPIOE_Pos        0
 #define SYS_PRSTR1_GPIOE_Msk        (0x01 << SYS_PRSTR1_GPIOE_Pos)
-#define SYS_PRSTR1_SPI2_Pos         8
-#define SYS_PRSTR1_SPI2_Msk         (0x01 << SYS_PRSTR1_SPI2_Pos)
 #define SYS_PRSTR1_SDRAM_Pos        12
 #define SYS_PRSTR1_SDRAM_Msk        (0x01 << SYS_PRSTR1_SDRAM_Pos)
+#define SYS_PRSTR1_SFC_Pos          13
+#define SYS_PRSTR1_SFC_Msk          (0x01 << SYS_PRSTR1_SFC_Pos)
 #define SYS_PRSTR1_ADC1_Pos         16
 #define SYS_PRSTR1_ADC1_Msk         (0x01 << SYS_PRSTR1_ADC1_Pos)
+#define SYS_PRSTR1_CAN1_Pos         17
+#define SYS_PRSTR1_CAN1_Msk         (0x01 << SYS_PRSTR1_CAN1_Pos)
 #define SYS_PRSTR1_RTC_Pos          19
 #define SYS_PRSTR1_RTC_Msk          (0x01 << SYS_PRSTR1_RTC_Pos)
 #define SYS_PRSTR1_IOFILT_Pos       20
@@ -491,6 +491,10 @@ typedef struct {
 #define SYS_PRSTR1_BTIMR_Msk        (0x01 << SYS_PRSTR1_BTIMR_Pos)
 #define SYS_PRSTR1_JPEG_Pos         25
 #define SYS_PRSTR1_JPEG_Msk         (0x01 << SYS_PRSTR1_JPEG_Pos)
+#define SYS_PRSTR1_DAC_Pos          26
+#define SYS_PRSTR1_DAC_Msk          (0x01 << SYS_PRSTR1_DAC_Pos)
+#define SYS_PRSTR1_QEI_Pos          27
+#define SYS_PRSTR1_QEI_Msk          (0x01 << SYS_PRSTR1_QEI_Pos)
 
 #define SYS_HRCCR_ON_Pos            0       //High speed RC ON
 #define SYS_HRCCR_ON_Msk            (0x01 << SYS_HRCCR_ON_Pos)
@@ -612,12 +616,12 @@ typedef struct {
 #define SYS_ACMPSR_CMP2IF_Pos       10
 #define SYS_ACMPSR_CMP2IF_Msk       (0x01 << SYS_ACMPSR_CMP2IF_Pos)
 
-#define SYS_ACMPCR2_HALL0_Pos       0       //1 ACMP0输出连接HALL0输入
-#define SYS_ACMPCR2_HALL0_Msk       (0x01 << SYS_ACMPCR2_HALL0_Pos)
-#define SYS_ACMPCR2_HALL1_Pos       1
-#define SYS_ACMPCR2_HALL1_Msk       (0x01 << SYS_ACMPCR2_HALL1_Pos)
-#define SYS_ACMPCR2_HALL2_Pos       2
-#define SYS_ACMPCR2_HALL2_Msk       (0x01 << SYS_ACMPCR2_HALL2_Pos)
+#define SYS_ACMPCR2_BRK0_Pos        0       //1 ACMP0输出连接用作PWM_BRK0
+#define SYS_ACMPCR2_BRK0_Msk        (0x01 << SYS_ACMPCR2_BRK0_Pos)
+#define SYS_ACMPCR2_BRK1_Pos        1       //1 ACMP1输出连接用作PWM_BRK1
+#define SYS_ACMPCR2_BRK1_Msk        (0x01 << SYS_ACMPCR2_BRK1_Pos)
+#define SYS_ACMPCR2_BRK2_Pos        2
+#define SYS_ACMPCR2_BRK2_Msk        (0x01 << SYS_ACMPCR2_BRK2_Pos)
 #define SYS_ACMPCR2_VREF_Pos        3       //ACMP内部基准电压VREF,电压值为 0.6 + 0.04*VREF
 #define SYS_ACMPCR2_VREF_Msk        (0x3F << SYS_ACMPCR2_VREF_Pos)
 
@@ -626,10 +630,6 @@ typedef struct {
 
 #define SYS_TEMPCR_EN_Pos           0
 #define SYS_TEMPCR_EN_Msk           (0x01 << SYS_TEMPCR_EN_Pos)
-#define SYS_TEMPCR_TRIM_Pos         4
-#define SYS_TEMPCR_TRIM_Msk         (0x3F << SYS_TEMPCR_TRIM_Pos)
-#define SYS_TEMPCR_AD0CH7_Pos       16      //ADC0 CH7通道测量信号选择,0 外部输入   1 温度传感器输出
-#define SYS_TEMPCR_AD0CH7_Msk       (0x03 << SYS_TEMPCR_AD0CH7_Pos)
 
 
 
@@ -754,6 +754,11 @@ typedef struct {
 } TIMR_TypeDef;
 
 
+#define TIMR_LOAD_VALUE_Pos         0
+#define TIMR_LOAD_VALUE_Msk         (0xFFFFFF << TIMR_LOAD_VALUE_Pos)
+#define TIMR_LOAD_RELOAD_Pos        24      //reload VALUE to TIMR's internal Counter immediately. only for BTIMRx, not for TIMRx.
+#define TIMR_LOAD_RELOAD_Msk        (0x01 << TIMR_LOAD_RELOAD_Pos)
+
 #define TIMR_CR_CLKSRC_Pos          0       //时钟源:  0 内部系统时钟    2 外部引脚脉冲计数
 #define TIMR_CR_CLKSRC_Msk          (0x03 << TIMR_CR_CLKSRC_Pos)
 #define TIMR_CR_MODE_Pos            2       //工作模式:0 定时器    1 输入捕获    2 输出比较
@@ -1001,6 +1006,8 @@ typedef struct {
 #define UART_RTSCR_STAT_Pos         8       //RTS信号的当前状态
 #define UART_RTSCR_STAT_Msk         (0x01 << UART_RTSCR_STAT_Pos)
 
+#define UART_CFG_RXEN_Pos           0       //RX Enable
+#define UART_CFG_RXEN_Msk           (0x01 << UART_CFG_RXEN_Pos)
 #define UART_CFG_MSBF_Pos           1       //接收发送MSB First
 #define UART_CFG_MSBF_Msk           (0x01 << UART_CFG_MSBF_Pos)
 #define UART_CFG_BRKTXLEN_Pos       2       //1表示1bit,以此类推,默认值13
@@ -1366,7 +1373,7 @@ typedef struct {
 #define ADC_GO_SEQ1_Pos             1
 #define ADC_GO_SEQ1_Msk             (0x01 << ADC_GO_SEQ1_Pos)
 #define ADC_GO_SEQ2_Pos             2
-#define ADC_GO_SEQ2_Msk             (0x01 << ADC_GO_SEQ3_Pos)
+#define ADC_GO_SEQ2_Msk             (0x01 << ADC_GO_SEQ2_Pos)
 #define ADC_GO_SEQ3_Pos             3
 #define ADC_GO_SEQ3_Msk             (0x01 << ADC_GO_SEQ3_Pos)
 #define ADC_GO_BUSY_Pos             4
@@ -1493,7 +1500,7 @@ typedef struct {
 #define ADC_CMP_MIN_Pos             16
 #define ADC_CMP_MIN_Msk             (0xFFF<< ADC_CMP_MIN_Pos)
 
-#define ADC_SEQCHN0_SEQ0_Pos        0       //序列0通道选择,8位对应8个通道,bitx置位表示将通道x加入序列0
+#define ADC_SEQCHN0_SEQ0_Pos        0       //序列0通道选择,12位对应12个通道,bitx置位表示将通道x加入序列0
 #define ADC_SEQCHN0_SEQ0_Msk        (0xFFF << ADC_SEQCHN0_SEQ0_Pos)
 #define ADC_SEQCHN0_SEQ1_Pos        16
 #define ADC_SEQCHN0_SEQ1_Msk        (0xFFF << ADC_SEQCHN0_SEQ1_Pos)
@@ -2558,6 +2565,8 @@ typedef struct {
 #define LCD_CR_CLKALW_Msk           (0x01 << LCD_CR_CLKALW_Pos)
 #define LCD_CR_BURSTEN_Pos          8       //Burst Enable,0 只进行SINGLE读   1 优先Burst读
 #define LCD_CR_BURSTEN_Msk          (0x01 << LCD_CR_BURSTEN_Pos)
+#define LCD_CR_BURSTLEN_Pos         9       //Burst Length,0 Burst INCR4   1 Burst INCR8
+#define LCD_CR_BURSTLEN_Msk         (0x01 << LCD_CR_BURSTLEN_Pos)
 #define LCD_CR_AUTORESTA_Pos        13      //Auto Restart,1 刷新完一帧后自动重启刷新
 #define LCD_CR_AUTORESTA_Msk        (0x01 << LCD_CR_AUTORESTA_Pos)
 #define LCD_CR_IMMRELOAD_Pos        14      //Immediate Reload,立即将层配置寄存器的值加载到层工作寄存器
@@ -2574,8 +2583,6 @@ typedef struct {
 #define LCD_CR_VSYNCINV_Msk         (0x01 << LCD_CR_VSYNCINV_Pos)
 #define LCD_CR_HSYNCINV_Pos         20      //1 HSYNC反相输出
 #define LCD_CR_HSYNCINV_Msk         (0x01 << LCD_CR_HSYNCINV_Pos)
-#define LCD_CR_BURSTLEN_Pos         21      //Burst Length,0 Burst INCR4   1 Burst INCR8   2 Burst INCR16
-#define LCD_CR_BURSTLEN_Msk         (0x03 << LCD_CR_BURSTLEN_Pos)
 
 #define LCD_CRH_HSW_Pos             0       //Hsync Width, 输出HSYNC低电平持续多少个DOTCLK周期,0表示1个周期
 #define LCD_CRH_HSW_Msk             (0xFF << LCD_CRH_HSW_Pos)
@@ -2675,8 +2682,8 @@ typedef struct {
 #define DMA2D_PFCCR_AINV_Msk        (0x01 << DMA2D_PFCCR_AINV_Pos)
 #define DMA2D_PFCCR_RBSWAP_Pos      4       //RB Swap, 0 RGB   1 BGR
 #define DMA2D_PFCCR_RBSWAP_Msk      (0x01 << DMA2D_PFCCR_RBSWAP_Pos)
-#define DAM2D_PFCCR_AMODE_Pos       8       //Alpha Mode, 0 使用像素点自带Alpha值   1 使用PFCCR.ALPHA值   2 使用像素点自带Alpha值与PFCCR.ALPHA值的乘积
-#define DMA2D_PFCCR_AMODE_Msk       (0x03 << DAM2D_PFCCR_AMODE_Pos)
+#define DMA2D_PFCCR_AMODE_Pos       8       //Alpha Mode, 0 使用像素点自带Alpha值   1 使用PFCCR.ALPHA值   2 使用像素点自带Alpha值与PFCCR.ALPHA值的乘积
+#define DMA2D_PFCCR_AMODE_Msk       (0x03 << DMA2D_PFCCR_AMODE_Pos)
 #define DMA2D_PFCCR_ALPHA_Pos       24
 #define DMA2D_PFCCR_ALPHA_Msk       (0xFFu<< DMA2D_PFCCR_ALPHA_Pos)
 
@@ -2703,8 +2710,8 @@ typedef struct {
 
 #define SDRAMC_TIM_TRCD_Pos         0       //Row to column delay, Ie. Activate to Command delay
 #define SDRAMC_TIM_TRCD_Msk         (0x03 << SDRAMC_TIM_TRCD_Pos)
-#define SDRAMC_TIM_TRFC_Pos         2       //Refresh Cycle
-#define SDRAMC_TIM_TRFC_Msk         (0x0F << SDRAMC_TIM_TRFC_Pos)
+#define SDRAMC_TIM_TRC_Pos          2       //Activate to Activate on same bank
+#define SDRAMC_TIM_TRC_Msk          (0x0F << SDRAMC_TIM_TRC_Pos)
 #define SDRAMC_TIM_TRP_Pos          6       //Row precharge time,  Ie. Precharge to Activate delay
 #define SDRAMC_TIM_TRP_Msk          (0x03 << SDRAMC_TIM_TRP_Pos)
 #define SDRAMC_TIM_T100US_Pos       8
@@ -2856,7 +2863,7 @@ typedef struct {
 
     __IO uint32_t ADDR;
 
-    __IO uint32_t FMC_ERASE;
+    __IO uint32_t ERASE;
 
     __IO uint32_t CACHE;
 
@@ -4005,4 +4012,51 @@ typedef struct {
 #include "SWM341_iofilt.h"
 
 
+#ifdef  SW_LOG_RTT
+#define log_printf(...)     SEGGER_RTT_printf(0, __VA_ARGS__)
+#else
+#define log_printf(...)     printf(__VA_ARGS__)
+#endif
+
+
+#ifndef SW_LOG_LEVEL
+#define SW_LOG_LEVEL        0
+#endif
+
+#if (SW_LOG_LEVEL > 0)
+#define SW_LOG_ERR(...)     {                        \
+                            log_printf("ERROR: ");   \
+                            log_printf(__VA_ARGS__); \
+                            log_printf("\n");        \
+                            }
+
+#if (SW_LOG_LEVEL > 1)
+#define SW_LOG_WARN(...)    {                        \
+                            log_printf("WARN : ");   \
+                            log_printf(__VA_ARGS__); \
+                            log_printf("\n");        \
+                            }
+
+#if (SW_LOG_LEVEL > 2)
+#define SW_LOG_INFO(...)    {                        \
+                            log_printf("INFO : ");   \
+                            log_printf(__VA_ARGS__); \
+                            log_printf("\n");        \
+                            }
+#else
+#define SW_LOG_INFO(...)
+#endif
+
+#else
+#define SW_LOG_WARN(...)
+#define SW_LOG_INFO(...)
+#endif
+
+#else
+#define SW_LOG_ERR(...)
+#define SW_LOG_WARN(...)
+#define SW_LOG_INFO(...)
+#endif
+
+
 #endif //__SWM341_H__

+ 2 - 2
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_adc.c

@@ -135,8 +135,8 @@ void ADC_SEQ_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_SEQ_InitStructure * init
     ADCx->SEQCOV &= ~(0xFFu << pos);
     ADCx->SEQCOV |= ((initStruct->conv_cnt ? initStruct->conv_cnt - 1 : 0) << pos);
 
-    ADCx->SEQSMP &= ~(0xFFu << pos);
-    ADCx->SEQSMP |= (initStruct->samp_tim << pos);
+    ADCx->SEQSMP &= ~(0x0Fu << (pos >> 1));
+    ADCx->SEQSMP |= (initStruct->samp_tim << (pos >> 1));
 }
 
 /******************************************************************************************************************************************

+ 18 - 3
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.c

@@ -392,7 +392,8 @@ void CAN_SetFilter16b(CAN_TypeDef * CANx, uint32_t filter, uint16_t check1, uint
 * 函数名称: CAN_INTEn()
 * 功能说明: 使能指定中断
 * 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN0、CAN1
-*           uint32_t it         interrupt type,有效值包括CAN_INT_RX_NOTEMPTY、CAN_INT_RX_OVERFLOW、CAN_INT_TX_EMPTY、...
+*           uint32_t it         interrupt type,有效值包括 CAN_IT_RX_NOTEMPTY、CAN_IT_RX_OVERFLOW、CAN_IT_TX_EMPTY、CAN_IT_ARBLOST、
+*                               CAN_IT_ERR、CAN_IT_ERR_WARN、CAN_IT_ERR_PASS、CAN_IT_WAKEUP 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
@@ -405,7 +406,8 @@ void CAN_INTEn(CAN_TypeDef * CANx, uint32_t it)
 * 函数名称: CAN_INTDis()
 * 功能说明: 关闭指定中断
 * 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN0、CAN1
-*           uint32_t it         interrupt type,有效值包括CAN_INT_RX_NOTEMPTY、CAN_INT_RX_OVERFLOW、CAN_INT_TX_EMPTY、...
+*           uint32_t it         interrupt type,有效值包括 CAN_IT_RX_NOTEMPTY、CAN_IT_RX_OVERFLOW、CAN_IT_TX_EMPTY、CAN_IT_ARBLOST、
+*                               CAN_IT_ERR、CAN_IT_ERR_WARN、CAN_IT_ERR_PASS、CAN_IT_WAKEUP 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
@@ -414,9 +416,22 @@ void CAN_INTDis(CAN_TypeDef * CANx, uint32_t it)
     CANx->IE &= ~it;
 }
 
+/******************************************************************************************************************************************
+* 函数名称: CAN_INTClr()
+* 功能说明: 清除中断标志
+* 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN0、CAN1
+*           uint32_t it         interrupt type,有效值包括 CAN_IT_RX_OVERFLOW
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void CAN_INTClr(CAN_TypeDef * CANx, uint32_t it)
+{
+    CANx->CMD = (1 << CAN_CMD_CLROV_Pos);
+}
+
 /******************************************************************************************************************************************
 * 函数名称: CAN_INTStat()
-* 功能说明: 查询指定中断状态
+* 功能说明: 查询中断状态
 * 输    入: CAN_TypeDef * CANx    指定要被设置的CAN接口,有效值包括CAN0、CAN1
 * 输    出: uint32_t          当前中断状态
 * 注意事项: CANx->IF读取清零,因此在中断ISR中只能读取一次,不能多次读取

+ 12 - 8
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.h

@@ -69,14 +69,17 @@ typedef struct {
 #define CAN_FILTER_15       14
 #define CAN_FILTER_16       15
 
-#define CAN_INT_RX_NOTEMPTY (0x01 << 0)     //RX Buffer Not Empty
-#define CAN_INT_RX_OVERFLOW (0x01 << 3)     //RX Buffer Overflow
-#define CAN_INT_TX_EMPTY    (0x01 << 1)     //TX Buffer Empty
-#define CAN_INT_ARBLOST     (0x01 << 6)     //Arbitration lost
-#define CAN_INT_ERR         (0x01 << 7)
-#define CAN_INT_ERR_WARN    (0x01 << 2)     //TXERR/RXERR计数值达到Error Warning Limit
-#define CAN_INT_ERR_PASS    (0x01 << 5)     //TXERR/RXERR计数值达到127
-#define CAN_INT_WAKEUP      (0x01 << 4)
+
+/* Interrupt Type */
+#define CAN_IT_RX_NOTEMPTY  (0x01 << 0)     //RX Buffer Not Empty
+#define CAN_IT_RX_OVERFLOW  (0x01 << 3)     //RX Buffer Overflow
+#define CAN_IT_TX_EMPTY     (0x01 << 1)     //TX Buffer Empty
+#define CAN_IT_ARBLOST      (0x01 << 6)     //Arbitration lost
+#define CAN_IT_ERR          (0x01 << 7)
+#define CAN_IT_ERR_WARN     (0x01 << 2)     //TXERR/RXERR计数值达到Error Warning Limit
+#define CAN_IT_ERR_PASS     (0x01 << 5)     //TXERR/RXERR计数值达到127
+#define CAN_IT_WAKEUP       (0x01 << 4)
+
 
 
 typedef struct {
@@ -111,6 +114,7 @@ void CAN_SetFilter16b(CAN_TypeDef * CANx, uint32_t filter, uint16_t check1, uint
 
 void CAN_INTEn(CAN_TypeDef * CANx, uint32_t it);
 void CAN_INTDis(CAN_TypeDef * CANx, uint32_t it);
+void CAN_INTClr(CAN_TypeDef * CANx, uint32_t it);
 uint32_t CAN_INTStat(CAN_TypeDef * CANx);
 
 

+ 5 - 2
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dac.c

@@ -39,6 +39,9 @@ void DAC_Init(DAC_TypeDef * DACx, uint32_t format)
         break;
     }
 
+    SYS->DACCR &= ~SYS_DACCR_VRADJ_Msk;
+    SYS->DACCR |= ((SYS->BACKUP[2] & 0x1F) << SYS_DACCR_VRADJ_Pos);
+
     DACx->CR = (format << DAC_CR_DHRFMT_Pos);
 }
 
@@ -51,11 +54,11 @@ void DAC_Init(DAC_TypeDef * DACx, uint32_t format)
 ******************************************************************************************************************************************/
 void DAC_Open(DAC_TypeDef * DACx)
 {
-    DACx->CR |= (1 << ADC_CR_EN_Pos);
+    DACx->CR |= (1 << DAC_CR_EN_Pos);
 }
 
 /******************************************************************************************************************************************
-* 函数名称: DAC_Init()
+* 函数名称: DAC_Close()
 * 功能说明: DAC 关闭
 * 输    入: DAC_TypeDef * DACx    指定要被设置的DAC接口,有效值包括DAC
 * 输    出: 无

+ 106 - 17
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.c

@@ -21,6 +21,7 @@
 #include "SWM341.h"
 #include "SWM341_dma.h"
 
+
 /******************************************************************************************************************************************
 * 函数名称: DMA_CH_Init()
 * 功能说明: DMA通道初始化
@@ -36,7 +37,7 @@ void DMA_CH_Init(uint32_t chn, DMA_InitStructure * initStruct)
     DMA_CH_Close(chn);      //关闭后配置
 
     DMA->CH[chn].CR = (initStruct->Mode << DMA_CR_AUTORE_Pos) |
-                      ((initStruct->Count - 1) << DMA_CR_LEN_Pos);
+                     ((initStruct->Count ? initStruct->Count - 1 : 0) << DMA_CR_LEN_Pos);
 
     DMA->CH[chn].SRC = initStruct->SrcAddr;
     DMA->CH[chn].DST = initStruct->DstAddr;
@@ -69,15 +70,35 @@ void DMA_CH_Init(uint32_t chn, DMA_InitStructure * initStruct)
         break;
     }
 
+    int totalBytes = initStruct->Count * (1 << initStruct->Unit);
+
+    if(initStruct->DstAddrInc == 2)     // Destination Scatter-Gather Transfer
+    {
+        DMA->CH[chn].DSTSGADDR1 = initStruct->DstAddr + totalBytes / 4 * 1;
+        DMA->CH[chn].DSTSGADDR2 = initStruct->DstAddr + totalBytes / 4 * 2;
+        DMA->CH[chn].DSTSGADDR3 = initStruct->DstAddr + totalBytes / 4 * 3;
+    }
+    if(initStruct->SrcAddrInc == 2)     // Source      Scatter-Gather Transfer
+    {
+        DMA->CH[chn].SRCSGADDR1 = initStruct->SrcAddr + totalBytes / 4 * 1;
+        DMA->CH[chn].SRCSGADDR2 = initStruct->SrcAddr + totalBytes / 4 * 2;
+        DMA->CH[chn].SRCSGADDR3 = initStruct->SrcAddr + totalBytes / 4 * 3;
+    }
+
     DMA->PRI &= ~(1 << chn);
     DMA->PRI |= (initStruct->Priority << chn);
 
-    DMA->IF  = (1 << chn);      //清除中断标志
-    DMA->IE |= (1 << chn);
-    if(initStruct->DoneIE)  DMA->IM &= ~(1 << chn);
-    else                    DMA->IM |=  (1 << chn);
+    DMA->IM |= (1 << chn);  // 默认全部关闭
+    DMA->DSTSGIM |= (3 << (chn * 2));
+    DMA->SRCSGIM |= (3 << (chn * 2));
+    DMA->IE |= (1 << chn);  // 标志总是可查
+    DMA->DSTSGIE |= (3 << (chn * 2));
+    DMA->SRCSGIE |= (3 << (chn * 2));
+
+    DMA_CH_INTClr(chn, initStruct->INTEn);
+    DMA_CH_INTEn(chn, initStruct->INTEn);
 
-    if(initStruct->DoneIE) NVIC_EnableIRQ(DMA_IRQn);
+    if(initStruct->INTEn) NVIC_EnableIRQ(DMA_IRQn);
 }
 
 /******************************************************************************************************************************************
@@ -104,50 +125,118 @@ void DMA_CH_Close(uint32_t chn)
     DMA->CH[chn].CR &= ~(DMA_CR_TXEN_Msk | DMA_CR_RXEN_Msk);
 }
 
+/******************************************************************************************************************************************
+* 函数名称: DMA_CH_SetCount()
+* 功能说明: 设置传输 Unit 个数
+* 输    入: uint32_t chn          指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
+*           uint32_t count          传输 Unit 个数,最大取值0x100000
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void DMA_CH_SetCount(uint32_t chn, uint32_t count)
+{
+    DMA->CH[chn].CR &= ~DMA_CR_LEN_Msk;
+    DMA->CH[chn].CR |= ((count - 1) << DMA_CR_LEN_Pos);
+}
+
+/******************************************************************************************************************************************
+* 函数名称: DMA_CH_GetRemaining()
+* 功能说明: 查询剩余的传输 Unit 个数
+* 输    入: uint32_t chn          指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
+* 输    出: uint32_t              剩余的传输 Unit 个数
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t DMA_CH_GetRemaining(uint32_t chn)
+{
+    return (DMA->CH[chn].DSTSR & DMA_DSTSR_LEN_Msk);
+}
+
+/******************************************************************************************************************************************
+* 函数名称: DMA_CH_SetSrcAddress()
+* 功能说明: 设置传输源地址
+* 输    入: uint32_t chn          指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
+*           uint32_t address        源地址
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void DMA_CH_SetSrcAddress(uint32_t chn, uint32_t address)
+{
+    DMA->CH[chn].SRC = address;
+}
+
+/******************************************************************************************************************************************
+* 函数名称: DMA_CH_SetDstAddress()
+* 功能说明: 设置传输目的地址
+* 输    入: uint32_t chn          指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
+*           uint32_t address        目的地址
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void DMA_CH_SetDstAddress(uint32_t chn, uint32_t address)
+{
+    DMA->CH[chn].DST = address;
+}
+
 /******************************************************************************************************************************************
 * 函数名称: DMA_CH_INTEn()
-* 功能说明: DMA中断使能,数据搬运完成后触发中断
+* 功能说明: DMA中断使能
 * 输    入: uint32_t chn          指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
+*           uint32_t it             interrupt type,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、
+*                                   DMA_IT_SRCSG_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void DMA_CH_INTEn(uint32_t chn)
+void DMA_CH_INTEn(uint32_t chn, uint32_t it)
 {
-    DMA->IM &= ~(1 << chn);
+    DMA->IM &= ~(it << chn);
+    DMA->DSTSGIM &= ~((it >>  8) << (chn * 2));
+    DMA->SRCSGIM &= ~((it >> 16) << (chn * 2));
 }
 
 /******************************************************************************************************************************************
 * 函数名称: DMA_CH_INTDis()
-* 功能说明: DMA中断禁止,数据搬运完成后不触发中断
+* 功能说明: DMA中断禁止
 * 输    入: uint32_t chn          指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
+*           uint32_t it             interrupt type,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、
+*                                   DMA_IT_SRCSG_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void DMA_CH_INTDis(uint32_t chn)
+void DMA_CH_INTDis(uint32_t chn, uint32_t it)
 {
-    DMA->IM |= (1 << chn);
+    DMA->IM |=  (it << chn);
+    DMA->DSTSGIM |=  ((it >>  8) << (chn * 2));
+    DMA->SRCSGIM |=  ((it >> 16) << (chn * 2));
 }
 
 /******************************************************************************************************************************************
 * 函数名称: DMA_CH_INTClr()
 * 功能说明: DMA中断标志清除
 * 输    入: uint32_t chn          指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
+*           uint32_t it             interrupt type,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、
+*                                   DMA_IT_SRCSG_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void DMA_CH_INTClr(uint32_t chn)
+void DMA_CH_INTClr(uint32_t chn, uint32_t it)
 {
-    DMA->IF = (1 << chn);
+    DMA->IF = (it << chn);
+    DMA->DSTSGIF = ((it >>  8) << (chn * 2));
+    DMA->SRCSGIF = ((it >> 16) << (chn * 2));
 }
 
 /******************************************************************************************************************************************
 * 函数名称: DMA_CH_INTStat()
 * 功能说明: DMA中断状态查询
 * 输    入: uint32_t chn          指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
-* 输    出: uint32_t              1 数据搬运完成    0 数据搬运未完成
+*           uint32_t it             interrupt type,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、
+*                                   DMA_IT_SRCSG_DONE 及其“或”
+* 输    出: uint32_t              1 指定中断已发生    0 指定中断未发生
 * 注意事项: 无
 ******************************************************************************************************************************************/
-uint32_t DMA_CH_INTStat(uint32_t chn)
+uint32_t DMA_CH_INTStat(uint32_t chn, uint32_t it)
 {
-    return (DMA->IF & (1 << chn)) ? 1 : 0;
+    return ((DMA->IF & (it << chn)) ||
+            (DMA->DSTSGIF & ((it >>  8) << (chn * 2))) ||
+            (DMA->SRCSGIF & ((it >> 16) << (chn * 2))));
 }

+ 18 - 5
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.h

@@ -21,7 +21,7 @@ typedef struct {
 
     uint8_t  Priority;      //DMA_PRI_LOW、DMA_PRI_HIGH
 
-    uint8_t  DoneIE;        //传输完成中断使能
+    uint32_t  INTEn;        //中断使能,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、DMA_IT_SRCSG_DONE 及其“或”
 } DMA_InitStructure;
 
 
@@ -97,15 +97,28 @@ typedef struct {
 #define DMA_EXHS_TRIG1      (6 | DMA_HS_EXT | DMA_DIR_RX)   // DMA_TRIG1引脚
 
 
+/* Interrupt Type */
+#define DMA_IT_DONE         (1 <<  0)   //Transfer Done
+#define DMA_IT_DSTSG_HALF   (1 <<  8)   //Destination Scatter-Gather Transfer Half
+#define DMA_IT_DSTSG_DONE   (1 <<  9)   //Destination Scatter-Gather Transfer Done
+#define DMA_IT_SRCSG_HALF   (1 << 16)   //Source      Scatter-Gather Transfer Half
+#define DMA_IT_SRCSG_DONE   (1 << 17)   //Source      Scatter-Gather Transfer Done
+
+
 
 void DMA_CH_Init(uint32_t chn, DMA_InitStructure * initStruct); //DMA通道配置
 void DMA_CH_Open(uint32_t chn);
 void DMA_CH_Close(uint32_t chn);
 
-void DMA_CH_INTEn(uint32_t chn);                //DMA中断使能,数据搬运完成后触发中断
-void DMA_CH_INTDis(uint32_t chn);               //DMA中断禁止,数据搬运完成后不触发中断
-void DMA_CH_INTClr(uint32_t chn);               //DMA中断标志清除
-uint32_t DMA_CH_INTStat(uint32_t chn);          //DMA中断状态查询,1 数据搬运完成    0 数据搬运未完成
+void DMA_CH_SetCount(uint32_t chn, uint32_t count);
+void DMA_CH_SetSrcAddress(uint32_t chn, uint32_t address);
+void DMA_CH_SetDstAddress(uint32_t chn, uint32_t address);
+uint32_t DMA_CH_GetRemaining(uint32_t chn);
+
+void DMA_CH_INTEn(uint32_t chn, uint32_t it);                   //DMA中断使能
+void DMA_CH_INTDis(uint32_t chn, uint32_t it);                  //DMA中断禁止
+void DMA_CH_INTClr(uint32_t chn, uint32_t it);                  //DMA中断标志清除
+uint32_t DMA_CH_INTStat(uint32_t chn, uint32_t it);             //DMA中断状态查询
 
 
 #endif //__SWM341_DMA_H__

+ 4 - 4
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma2d.c

@@ -135,14 +135,14 @@ void DMA2D_PixelBlend(DMA2D_LayerSetting * fgLayer, DMA2D_LayerSetting * bgLayer
 {
     DMA2D->L[DMA2D_LAYER_FG].MAR = fgLayer->Address;
     DMA2D->L[DMA2D_LAYER_FG].OR  = fgLayer->LineOffset;
-    DMA2D->L[DMA2D_LAYER_FG].PFCCR = (fgLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos)  |
-                                     (fgLayer->AlphaMode << DAM2D_PFCCR_AMODE_Pos) |
+    DMA2D->L[DMA2D_LAYER_FG].PFCCR = (fgLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos) |
+                                     (fgLayer->AlphaMode << DMA2D_PFCCR_AINV_Pos) |
                                      (fgLayer->Alpha     << DMA2D_PFCCR_ALPHA_Pos);
 
     DMA2D->L[DMA2D_LAYER_BG].MAR = bgLayer->Address;
     DMA2D->L[DMA2D_LAYER_BG].OR  = bgLayer->LineOffset;
-    DMA2D->L[DMA2D_LAYER_BG].PFCCR = (bgLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos)  |
-                                     (bgLayer->AlphaMode << DAM2D_PFCCR_AMODE_Pos) |
+    DMA2D->L[DMA2D_LAYER_BG].PFCCR = (bgLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos) |
+                                     (bgLayer->AlphaMode << DMA2D_PFCCR_AINV_Pos) |
                                      (bgLayer->Alpha     << DMA2D_PFCCR_ALPHA_Pos);
 
     DMA2D->L[DMA2D_LAYER_OUT].MAR = outLayer->Address;

+ 4 - 43
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.c

@@ -111,7 +111,7 @@ void GPIO_Init(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t dir, uint32_t pull_up,
 ******************************************************************************************************************************************/
 void GPIO_SetBit(GPIO_TypeDef * GPIOx, uint32_t n)
 {
-    GPIOx->ODR |= (0x01 << n);
+    *(&GPIOx->DATAPIN0 + n) = 1;
 }
 
 /******************************************************************************************************************************************
@@ -124,7 +124,7 @@ void GPIO_SetBit(GPIO_TypeDef * GPIOx, uint32_t n)
 ******************************************************************************************************************************************/
 void GPIO_ClrBit(GPIO_TypeDef * GPIOx, uint32_t n)
 {
-    GPIOx->ODR &= ~(0x01 << n);
+    *(&GPIOx->DATAPIN0 + n) = 0;
 }
 
 /******************************************************************************************************************************************
@@ -137,7 +137,7 @@ void GPIO_ClrBit(GPIO_TypeDef * GPIOx, uint32_t n)
 ******************************************************************************************************************************************/
 void GPIO_InvBit(GPIO_TypeDef * GPIOx, uint32_t n)
 {
-    GPIOx->ODR ^= (0x01 << n);
+    *(&GPIOx->DATAPIN0 + n) = 1 - *(&GPIOx->DATAPIN0 + n);
 }
 
 /******************************************************************************************************************************************
@@ -150,7 +150,7 @@ void GPIO_InvBit(GPIO_TypeDef * GPIOx, uint32_t n)
 ******************************************************************************************************************************************/
 uint32_t GPIO_GetBit(GPIO_TypeDef * GPIOx, uint32_t n)
 {
-    return ((GPIOx->IDR >> n) & 0x01);
+    return *(&GPIOx->DATAPIN0 + n);
 }
 
 /******************************************************************************************************************************************
@@ -226,45 +226,6 @@ uint32_t GPIO_GetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
     return ((GPIOx->IDR >> n) & bits);
 }
 
-/******************************************************************************************************************************************
-* 函数名称: GPIO_AtomicSetBit()
-* 功能说明: 将参数指定的引脚电平置高,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
-* 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOM、GPION
-*           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
-* 输    出: 无
-* 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
-******************************************************************************************************************************************/
-void GPIO_AtomicSetBit(GPIO_TypeDef * GPIOx, uint32_t n)
-{
-    *(&GPIOx->DATAPIN0 + n) = 1;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: GPIO_AtomicClrBit()
-* 功能说明: 将参数指定的引脚电平置低,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
-* 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOM、GPION
-*           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
-* 输    出: 无
-* 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
-******************************************************************************************************************************************/
-void GPIO_AtomicClrBit(GPIO_TypeDef * GPIOx, uint32_t n)
-{
-    *(&GPIOx->DATAPIN0 + n) = 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: GPIO_AtomicInvBit()
-* 功能说明: 将参数指定的引脚电平反转,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
-* 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOM、GPION
-*           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
-* 输    出: 无
-* 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
-******************************************************************************************************************************************/
-void GPIO_AtomicInvBit(GPIO_TypeDef * GPIOx, uint32_t n)
-{
-    *(&GPIOx->DATAPIN0 + n) = 1 - *(&GPIOx->DATAPIN0 + n);
-}
-
 /******************************************************************************************************************************************
 * 函数名称: GPIO_AtomicSetBits()
 * 功能说明: 将参数指定的从n开始的w位连续引脚的电平置高,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)

+ 17 - 3
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.h

@@ -4,6 +4,16 @@
 
 void GPIO_Init(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t dir, uint32_t pull_up, uint32_t pull_down, uint32_t open_drain);  //引脚初始化,包含引脚方向、上拉、下拉、开漏
 
+#define GPIO_INPUT                      ((0 << 0) | (0 << 1) | (0 << 2) | (0 << 3))
+#define GPIO_INPUT_PullUp               ((0 << 0) | (1 << 1) | (0 << 2) | (0 << 3))
+#define GPIO_INPUT_PullDown             ((0 << 0) | (0 << 1) | (1 << 2) | (0 << 3))
+#define GPIO_OUTPUT                     ((1 << 0) | (0 << 1) | (0 << 2) | (0 << 3))
+#define GPIO_OUTPUT_OpenDrain           ((1 << 0) | (0 << 1) | (0 << 2) | (1 << 3))
+#define GPIO_OUTPUT_OpenDrain_PullUp    ((1 << 0) | (1 << 1) | (0 << 2) | (1 << 3))
+
+#define GPIO_INIT(GPIOx, n, mode)  GPIO_Init(GPIOx, n, (mode & 1) ? 1 : 0, (mode & 2) ? 1 : 0, (mode & 4) ? 1 : 0, (mode & 8) ? 1 : 0)
+
+
 void GPIO_SetBit(GPIO_TypeDef * GPIOx, uint32_t n);                     //将参数指定的引脚电平置高
 void GPIO_ClrBit(GPIO_TypeDef * GPIOx, uint32_t n);                     //将参数指定的引脚电平置低
 void GPIO_InvBit(GPIO_TypeDef * GPIOx, uint32_t n);                     //将参数指定的引脚电平反转
@@ -13,12 +23,16 @@ void GPIO_ClrBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);        //将参
 void GPIO_InvBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);        //将参数指定的从n开始的w位连续引脚的电平反转
 uint32_t GPIO_GetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);    //读取参数指定的从n开始的w位连续引脚的电平状态
 
-void GPIO_AtomicSetBit(GPIO_TypeDef * GPIOx, uint32_t n);
-void GPIO_AtomicClrBit(GPIO_TypeDef * GPIOx, uint32_t n);
-void GPIO_AtomicInvBit(GPIO_TypeDef * GPIOx, uint32_t n);
+
 void GPIO_AtomicSetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);
 void GPIO_AtomicClrBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);
 void GPIO_AtomicInvBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w);
 
 
+// for compatibility
+#define GPIO_AtomicSetBit   GPIO_SetBit
+#define GPIO_AtomicClrBit   GPIO_ClrBit
+#define GPIO_AtomicInvBit   GPIO_InvBit
+
+
 #endif //__SWM341_GPIO_H__

+ 1 - 1
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_lcd.c

@@ -47,7 +47,7 @@ void LCD_Init(LCD_TypeDef * LCDx, LCD_InitStructure * initStruct)
                 ((initStruct->Format & 1)  << LCD_CR_FORMAT_Pos)   |
                 ((initStruct->Format >> 1) << LCD_CR_SEREN_Pos)    |
                 (1                         << LCD_CR_BURSTEN_Pos)  |
-                (0                         << LCD_CR_BURSTLEN_Pos) |
+                (1                         << LCD_CR_BURSTLEN_Pos) |
                 ((1-initStruct->IntEOTEn)  << LCD_CR_AUTORESTA_Pos);
 
     LCDx->CRH = ((initStruct->HsyncWidth - 1) << LCD_CRH_HSW_Pos) |

+ 24 - 208
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.c

@@ -185,241 +185,57 @@ static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date)
 }
 
 /******************************************************************************************************************************************
-* 函数名称: RTC_IntSecondEn()
-* 功能说明: 中断使能
+* 函数名称: RTC_INTEn()
+* 功能说明: 中断使能
 * 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
+*           uint32_t it             interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM、
+*                                           RTC_IT_SECOND_DIV2、RTC_IT_SECOND_DIV4
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void RTC_IntSecondEn(RTC_TypeDef * RTCx)
+void RTC_INTEn(RTC_TypeDef * RTCx, uint32_t it)
 {
-    RTCx->IE |= (1 << RTC_IE_SEC_Pos);
+    RTCx->IE |= it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: RTC_IntSecondDis()
-* 功能说明: 中断禁止
+* 函数名称: RTC_INTDis()
+* 功能说明: 中断禁止
 * 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
+*           uint32_t it             interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM、
+*                                           RTC_IT_SECOND_DIV2、RTC_IT_SECOND_DIV4
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void RTC_IntSecondDis(RTC_TypeDef * RTCx)
+void RTC_INTDis(RTC_TypeDef * RTCx, uint32_t it)
 {
-    RTCx->IE &= ~(1 << RTC_IE_SEC_Pos);
+    RTCx->IE &= ~it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: RTC_IntSecondClr()
-* 功能说明: 中断标志清除
+* 函数名称: RTC_INTClr()
+* 功能说明: 中断标志清除
 * 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
+*           uint32_t it             interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM、
+*                                           RTC_IT_SECOND_DIV2、RTC_IT_SECOND_DIV4
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void RTC_IntSecondClr(RTC_TypeDef * RTCx)
+void RTC_INTClr(RTC_TypeDef * RTCx, uint32_t it)
 {
-    RTCx->IF = (1 << RTC_IF_SEC_Pos);
+    RTCx->IF = it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: RTC_IntSecondStat()
-* 功能说明: 中断状态
+* 函数名称: RTC_INTStat()
+* 功能说明: 中断状态
 * 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
+*           uint32_t it             interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM、
+*                                           RTC_IT_SECOND_DIV2、RTC_IT_SECOND_DIV4
 * 输    出: uint32_t              1 秒中断发生    0 秒中断未发生
 * 注意事项: 无
 ******************************************************************************************************************************************/
-uint32_t RTC_IntSecondStat(RTC_TypeDef * RTCx)
+uint32_t RTC_INTStat(RTC_TypeDef * RTCx, uint32_t it)
 {
-    return (RTCx->IF & RTC_IF_SEC_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntMinuteEn()
-* 功能说明: 分中断使能
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntMinuteEn(RTC_TypeDef * RTCx)
-{
-    RTCx->IE |= (1 << RTC_IE_MIN_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntMinuteDis()
-* 功能说明: 分中断禁止
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntMinuteDis(RTC_TypeDef * RTCx)
-{
-    RTCx->IE &= ~(1 << RTC_IE_MIN_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntMinuteClr()
-* 功能说明: 分中断标志清除
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntMinuteClr(RTC_TypeDef * RTCx)
-{
-    RTCx->IF = (1 << RTC_IF_MIN_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntMinuteStat()
-* 功能说明: 分中断状态
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: uint32_t              1 分中断发生    0 分中断未发生
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t RTC_IntMinuteStat(RTC_TypeDef * RTCx)
-{
-    return (RTCx->IF & RTC_IF_MIN_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntHourEn()
-* 功能说明: 时中断使能
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntHourEn(RTC_TypeDef * RTCx)
-{
-    RTCx->IE |= (1 << RTC_IE_HOUR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntHourDis()
-* 功能说明: 时中断禁止
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntHourDis(RTC_TypeDef * RTCx)
-{
-    RTCx->IE &= ~(1 << RTC_IE_HOUR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntHourClr()
-* 功能说明: 时中断标志清除
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntHourClr(RTC_TypeDef * RTCx)
-{
-    RTCx->IF = (1 << RTC_IF_HOUR_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntHourStat()
-* 功能说明: 时中断状态
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: uint32_t              1 时中断发生    0 时中断未发生
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t RTC_IntHourStat(RTC_TypeDef * RTCx)
-{
-    return (RTCx->IF & RTC_IF_HOUR_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntDateEn()
-* 功能说明: 日中断使能
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntDateEn(RTC_TypeDef * RTCx)
-{
-    RTCx->IE |= (1 << RTC_IE_DATE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntDateDis()
-* 功能说明: 日中断禁止
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntDateDis(RTC_TypeDef * RTCx)
-{
-    RTCx->IE &= ~(1 << RTC_IE_DATE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntDateClr()
-* 功能说明: 日中断标志清除
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntDateClr(RTC_TypeDef * RTCx)
-{
-    RTCx->IF = (1 << RTC_IF_DATE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntDateStat()
-* 功能说明: 日中断状态
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: uint32_t              1 日中断发生    0 日中断未发生
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t RTC_IntDateStat(RTC_TypeDef * RTCx)
-{
-    return (RTCx->IF & RTC_IF_DATE_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntAlarmEn()
-* 功能说明: 闹钟中断使能
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntAlarmEn(RTC_TypeDef * RTCx)
-{
-    RTCx->IE |= (1 << RTC_IE_ALARM_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntAlarmDis()
-* 功能说明: 闹钟中断禁止
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntAlarmDis(RTC_TypeDef * RTCx)
-{
-    RTCx->IE &= ~(1 << RTC_IE_ALARM_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntAlarmClr()
-* 功能说明: 闹钟中断标志清除
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void RTC_IntAlarmClr(RTC_TypeDef * RTCx)
-{
-    RTCx->IF = (1 << RTC_IF_ALARM_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: RTC_IntAlarmStat()
-* 功能说明: 闹钟中断状态
-* 输    入: RTC_TypeDef * RTCx        指定要被设置的RTC,可取值包括RTC
-* 输    出: uint32_t              1 闹钟中断发生    0 闹钟中断未发生
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t RTC_IntAlarmStat(RTC_TypeDef * RTCx)
-{
-    return (RTCx->IF & RTC_IF_ALARM_Msk) ? 1 : 0;
+    return (RTCx->IF & it) ? 1 : 0;
 }

+ 16 - 20
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.h

@@ -44,6 +44,18 @@ typedef struct {
     uint8_t  Second;
 } RTC_DateTime;
 
+
+/* Interrupt Type */
+#define RTC_IT_SECOND       (1 << 0)    //Second Interrupt
+#define RTC_IT_MINUTE       (1 << 1)
+#define RTC_IT_HOUR         (1 << 2)
+#define RTC_IT_DATE         (1 << 3)
+#define RTC_IT_ALARM        (1 << 4)
+#define RTC_IT_SECOND_DIV2  (1 << 6)    //1/2 Second Interrupt
+#define RTC_IT_SECOND_DIV4  (1 << 7)    //1/4 Second Interrupt
+
+
+
 void RTC_Init(RTC_TypeDef * RTCx, RTC_InitStructure * initStruct);
 void RTC_Start(RTC_TypeDef * RTCx);
 void RTC_Stop(RTC_TypeDef * RTCx);
@@ -53,25 +65,9 @@ void RTC_GetDateTime(RTC_TypeDef * RTCx, RTC_DateTime * dateTime);
 void RTC_AlarmSetup(RTC_TypeDef * RTCx, RTC_AlarmStructure * alarmStruct);
 
 
-void RTC_IntSecondEn(RTC_TypeDef * RTCx);
-void RTC_IntSecondDis(RTC_TypeDef * RTCx);
-void RTC_IntSecondClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntSecondStat(RTC_TypeDef * RTCx);
-void RTC_IntMinuteEn(RTC_TypeDef * RTCx);
-void RTC_IntMinuteDis(RTC_TypeDef * RTCx);
-void RTC_IntMinuteClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntMinuteStat(RTC_TypeDef * RTCx);
-void RTC_IntHourEn(RTC_TypeDef * RTCx);
-void RTC_IntHourDis(RTC_TypeDef * RTCx);
-void RTC_IntHourClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntHourStat(RTC_TypeDef * RTCx);
-void RTC_IntDateEn(RTC_TypeDef * RTCx);
-void RTC_IntDateDis(RTC_TypeDef * RTCx);
-void RTC_IntDateClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntDateStat(RTC_TypeDef * RTCx);
-void RTC_IntAlarmEn(RTC_TypeDef * RTCx);
-void RTC_IntAlarmDis(RTC_TypeDef * RTCx);
-void RTC_IntAlarmClr(RTC_TypeDef * RTCx);
-uint32_t RTC_IntAlarmStat(RTC_TypeDef * RTCx);
+void RTC_INTEn(RTC_TypeDef * RTCx, uint32_t it);
+void RTC_INTDis(RTC_TypeDef * RTCx, uint32_t it);
+void RTC_INTClr(RTC_TypeDef * RTCx, uint32_t it);
+uint32_t RTC_INTStat(RTC_TypeDef * RTCx, uint32_t it);
 
 #endif //__SWM341_RTC_H__

+ 275 - 2
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.c

@@ -59,6 +59,8 @@ uint32_t SDIO_Init(uint32_t freq)
 
     while((SDIO->CR2 & SDIO_CR2_CLKRDY_Msk) == 0);
 
+    for(int i = 0; i < CyclesPerUs * 10; i++) __NOP();
+
     SDIO->IM = 0xFFFFFFFF;
 
 
@@ -77,7 +79,7 @@ uint32_t SDIO_Init(uint32_t freq)
         if(res != SD_RES_OK)
             return res;
 
-        if(resp != 0x120) return SD_RES_ERR;    //不是SD卡,可能是MMC卡
+        if((resp & SD_CS_APP_CMD) == 0) return SD_RES_ERR;
 
         if(SD_cardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V2_0)
             SDIO_SendCmd(SD_CMD_SD_APP_OP_COND, 0x80100000|0x40000000, SD_RESP_32b, &resp);
@@ -348,7 +350,7 @@ uint32_t _SDIO_SendCmd(uint32_t cmd, uint32_t arg, uint32_t resp_type, uint32_t
                 (data_read       << SDIO_CMD_DIRREAD_Pos)   |
                 ((block_cnt > 1) << SDIO_CMD_MULTBLK_Pos)   |
                 ((block_cnt > 1) << SDIO_CMD_BLKCNTEN_Pos)  |
-                ((block_cnt > 1) << SDIO_CMD_AUTOCMD12_Pos) |
+                (((cmd == 53) ? 0 : (block_cnt > 1)) << SDIO_CMD_AUTOCMD12_Pos) |
                 (use_dma         << SDIO_CMD_DMAEN_Pos);
 
     while((SDIO->IF & SDIO_IF_CMDDONE_Msk) == 0)
@@ -602,3 +604,274 @@ uint32_t calcSDCLKDiv(uint32_t freq)
 
     return regdiv;
 }
+
+
+/******************************************************************************************************************************************
+* 函数名称: SDIO_IO_Init()
+* 功能说明: SDIO读写IO卡初始化
+* 输    入: uint32_t freq         SDIO_CLK时钟频率
+*           enum SDIO_bus_width w   SDIO_1bit 1-bit bus   SDIO_4bit 4-bit bus
+* 输    出: uint32_t              SD_RES_OK 操作成功    SD_RES_ERR 操作失败    SD_RES_TIMEOUT 操作超时
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t SDIO_IO_Init(uint32_t freq, enum SDIO_bus_width w)
+{
+    uint32_t res;
+    uint32_t resp, resps[4];
+
+    SYS->CLKSEL &= ~SYS_CLKSEL_SDIO_Msk;
+    if(SystemCoreClock > 80000000)      //SDIO时钟需要小于52MHz
+        SYS->CLKSEL |= (2 << SYS_CLKSEL_SDIO_Pos);  //SDCLK = SYSCLK / 4
+    else
+        SYS->CLKSEL |= (0 << SYS_CLKSEL_SDIO_Pos);  //SDCLK = SYSCLK / 2
+
+    SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_SDIO_Pos);
+
+//  SDIO->CR2 = (1 << SDIO_CR2_RSTALL_Pos);
+    for(int i = 0; i < CyclesPerUs; i++) __NOP();
+
+    SDIO->CR1 = (1 << SDIO_CR1_CDSRC_Pos) |
+                (0 << SDIO_CR1_8BIT_Pos)  |
+                (w << SDIO_CR1_4BIT_Pos)  |
+                (1 << SDIO_CR1_PWRON_Pos) |
+                (7 << SDIO_CR1_VOLT_Pos);
+
+    SDIO->CR2 = (1 << SDIO_CR2_CLKEN_Pos) |
+                (1 << SDIO_CR2_SDCLKEN_Pos) |
+                (calcSDCLKDiv(freq) << SDIO_CR2_SDCLKDIV_Pos) |
+                (0xC << SDIO_CR2_TIMEOUT_Pos);      // 2**25 SDIO_CLK
+
+    while((SDIO->CR2 & SDIO_CR2_CLKRDY_Msk) == 0);
+
+    for(int i = 0; i < CyclesPerUs * 10; i++) __NOP();
+
+    SDIO->IM = 0xFFFFFFFF;
+
+    return SD_RES_OK;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: SDIO_IO_ByteWrite()
+* 功能说明: 向IO卡写入单个字节
+* 输    入: uint8_t func          The number of the function within the I/O card you wish to read or write
+*           uint32_t addr           Start Address of I/O register to read or write. Range is 0--0x1FFFF
+*           uint32_t buff[]         要写出的数据
+*           uint16_t block_size     要写出的字节个数,取值 1--512
+* 输    出: uint32_t              SD_RES_OK 操作成功    SD_RES_ERR 操作失败    SD_RES_TIMEOUT 操作超时
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t SDIO_IO_ByteWrite(uint8_t func, uint32_t addr, uint8_t data)
+{
+    uint32_t res;
+    uint32_t arg, resp;
+
+    arg = (1u   << SD_CMD53_ARG_nRW) |
+          (func << SD_CMD53_ARG_Function) |
+          (addr << SD_CMD53_ARG_Addr) | data;
+
+    res = SDIO_SendCmd(52, arg, SD_RESP_32b, &resp);
+    if(res != SD_RES_OK)
+        return res;
+
+    return SD_RES_OK;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: SDIO_IO_ByteRead()
+* 功能说明: 从IO卡读出单个字节
+* 输    入: uint8_t func          The number of the function within the I/O card you wish to read or write
+*           uint32_t addr           Start Address of I/O register to read or write. Range is 0--0x1FFFF
+*           uint32_t buff[]         读取到的数据存入此数组
+*           uint16_t block_size     要读取的字节个数,取值 1--512
+* 输    出: uint32_t              SD_RES_OK 操作成功    SD_RES_ERR 操作失败    SD_RES_TIMEOUT 操作超时
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t SDIO_IO_ByteRead(uint8_t func, uint32_t addr, uint8_t * data)
+{
+    uint32_t res;
+    uint32_t arg, resp;
+
+    arg = (0u   << SD_CMD53_ARG_nRW) |
+          (func << SD_CMD53_ARG_Function) |
+          (addr << SD_CMD53_ARG_Addr) | 0x00;
+
+    res = SDIO_SendCmd(52, arg, SD_RESP_32b, &resp);
+    if(res != SD_RES_OK)
+        return res;
+
+    *data = resp & 0xFF;
+
+    return SD_RES_OK;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: SDIO_IO_BlockWrite()
+* 功能说明: 向IO卡写入单个块数据
+* 输    入: uint8_t func          The number of the function within the I/O card you wish to read or write
+*           uint32_t addr           Start Address of I/O register to read or write. Range is 0--0x1FFFF
+*           uint8_t addrInc         0 Multi byte R/W to fixed address   1 Multi byte R/W to incrementing address
+*           uint32_t buff[]         要写出的数据
+*           uint16_t block_size     要写出的字节个数,取值 1--512
+* 输    出: uint32_t              SD_RES_OK 操作成功    SD_RES_ERR 操作失败    SD_RES_TIMEOUT 操作超时
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t SDIO_IO_BlockWrite(uint8_t func, uint32_t addr, uint8_t addrInc, uint32_t buff[], uint16_t block_size)
+{
+    uint32_t res, i;
+    uint32_t arg, resp;
+
+    SDIO->BLK = block_size;
+
+    arg = (1u                   << SD_CMD53_ARG_nRW) |
+          (func                 << SD_CMD53_ARG_Function) |
+          (addr                 << SD_CMD53_ARG_Addr) |
+          (addrInc              << SD_CMD53_ARG_AddrInc) |
+          ((block_size % 512)   << SD_CMD53_ARG_Count) |
+          (0                    << SD_CMD53_ARG_CountUnit);
+
+    res = SDIO_SendCmdWithData(53, arg, SD_RESP_32b, &resp, 0, 1);
+    if(res != SD_RES_OK)
+        return res;
+
+    while((SDIO->IF & SDIO_IF_BUFWRRDY_Msk) == 0) __NOP();
+    SDIO->IF = SDIO_IF_BUFWRRDY_Msk;
+
+    for(i = 0; i < block_size/4; i++) SDIO->DATA = buff[i];
+
+    while((SDIO->IF & SDIO_IF_TRXDONE_Msk) == 0) __NOP();
+    SDIO->IF = SDIO_IF_TRXDONE_Msk;
+
+    return SD_RES_OK;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: SDIO_IO_BlockRead()
+* 功能说明: 从IO卡读出单个块数据
+* 输    入: uint8_t func          The number of the function within the I/O card you wish to read or write
+*           uint32_t addr           Start Address of I/O register to read or write. Range is 0--0x1FFFF
+*           uint8_t addrInc         0 Multi byte R/W to fixed address   1 Multi byte R/W to incrementing address
+*           uint32_t buff[]         读取到的数据存入此数组
+*           uint16_t block_size     要读取的字节个数,取值 1--512
+* 输    出: uint32_t              SD_RES_OK 操作成功    SD_RES_ERR 操作失败    SD_RES_TIMEOUT 操作超时
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t SDIO_IO_BlockRead(uint8_t func, uint32_t addr, uint8_t addrInc, uint32_t buff[], uint16_t block_size)
+{
+    uint32_t res, i;
+    uint32_t arg, resp;
+
+    SDIO->BLK = block_size;
+
+    arg = (0u                   << SD_CMD53_ARG_nRW) |
+          (func                 << SD_CMD53_ARG_Function) |
+          (addr                 << SD_CMD53_ARG_Addr) |
+          (addrInc              << SD_CMD53_ARG_AddrInc) |
+          ((block_size % 512)   << SD_CMD53_ARG_Count) |
+          (0                    << SD_CMD53_ARG_CountUnit);
+
+    res = SDIO_SendCmdWithData(53, arg, SD_RESP_32b, &resp, 1, 1);
+    if(res != SD_RES_OK)
+        return res;
+
+    while((SDIO->IF & SDIO_IF_BUFRDRDY_Msk) == 0) __NOP();
+    SDIO->IF = SDIO_IF_BUFRDRDY_Msk;
+
+    for(i = 0; i < block_size/4; i++) buff[i] = SDIO->DATA;
+
+    while((SDIO->IF & SDIO_IF_TRXDONE_Msk) == 0) __NOP();
+    SDIO->IF = SDIO_IF_TRXDONE_Msk;
+
+    return SD_RES_OK;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: SDIO_IO_MultiBlockWrite()
+* 功能说明: 向IO卡写入多个块数据
+* 输    入: uint8_t func          The number of the function within the I/O card you wish to read or write
+*           uint32_t addr           Start Address of I/O register to read or write. Range is 0--0x1FFFF
+*           uint8_t addrInc         0 Multi byte R/W to fixed address   1 Multi byte R/W to incrementing address
+*           uint32_t buff[]         要写出的数据
+*           uint16_t block_count    要写出的块个数,块大小为 512 字节
+* 输    出: uint32_t              SD_RES_OK 操作成功    SD_RES_ERR 操作失败    SD_RES_TIMEOUT 操作超时
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t SDIO_IO_MultiBlockWrite(uint8_t func, uint32_t addr, uint8_t addrInc, uint32_t buff[], uint16_t block_count)
+{
+    uint32_t res, i, j;
+    uint32_t arg, resp;
+
+    SDIO->BLK = 512;
+
+    arg = (1u           << SD_CMD53_ARG_nRW) |
+          (func         << SD_CMD53_ARG_Function) |
+          (addr         << SD_CMD53_ARG_Addr) |
+          (addrInc      << SD_CMD53_ARG_AddrInc) |
+          (block_count  << SD_CMD53_ARG_Count) |
+          (1            << SD_CMD53_ARG_CountUnit);
+
+    res = SDIO_SendCmdWithData(53, arg, SD_RESP_32b, &resp, 0, block_count);
+    if(res != SD_RES_OK)
+        return res;
+
+    for(i = 0; i < block_count; i++)
+    {
+        while((SDIO->IF & SDIO_IF_BUFWRRDY_Msk) == 0) __NOP();
+        SDIO->IF = SDIO_IF_BUFWRRDY_Msk;
+
+        for(j = 0; j < 512/4; j++) SDIO->DATA = buff[i*(512/4) + j];
+    }
+
+    while((SDIO->IF & SDIO_IF_TRXDONE_Msk) == 0) __NOP();
+    SDIO->IF = SDIO_IF_TRXDONE_Msk;
+
+    return SD_RES_OK;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: SDIO_IO_MultiBlockRead()
+* 功能说明: 从IO卡读出多个块数据
+* 输    入: uint8_t func          The number of the function within the I/O card you wish to read or write
+*           uint32_t addr           Start Address of I/O register to read or write. Range is 0--0x1FFFF
+*           uint8_t addrInc         0 Multi byte R/W to fixed address   1 Multi byte R/W to incrementing address
+*           uint32_t buff[]         读取到的数据存入此数组
+*           uint16_t block_count    要读取的块个数,块大小为 512 字节
+* 输    出: uint32_t              SD_RES_OK 操作成功    SD_RES_ERR 操作失败    SD_RES_TIMEOUT 操作超时
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t SDIO_IO_MultiBlockRead(uint8_t func, uint32_t addr, uint8_t addrInc, uint32_t buff[], uint16_t block_count)
+{
+    uint32_t res, i, j;
+    uint32_t arg, resp;
+
+    SDIO->BLK = 512;
+
+    arg = (0u           << SD_CMD53_ARG_nRW) |
+          (func         << SD_CMD53_ARG_Function) |
+          (addr         << SD_CMD53_ARG_Addr) |
+          (addrInc      << SD_CMD53_ARG_AddrInc) |
+          (block_count  << SD_CMD53_ARG_Count) |
+          (1            << SD_CMD53_ARG_CountUnit);
+
+    res = SDIO_SendCmdWithData(53, arg, SD_RESP_32b, &resp, 1, block_count);
+    if(res != SD_RES_OK)
+        return res;
+
+    for(i = 0; i < block_count; i++)
+    {
+        while((SDIO->IF & SDIO_IF_BUFRDRDY_Msk) == 0) __NOP();
+        SDIO->IF = SDIO_IF_BUFRDRDY_Msk;
+
+        for(j = 0; j < 512/4; j++) buff[i*(512/4) + j] = SDIO->DATA;
+    }
+
+    while((SDIO->IF & SDIO_IF_TRXDONE_Msk) == 0) __NOP();
+    SDIO->IF = SDIO_IF_TRXDONE_Msk;
+
+    return SD_RES_OK;
+}

+ 27 - 0
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.h

@@ -34,6 +34,13 @@
 #define SD_CMD_SDIO_RW_DIRECT                      ((uint8_t)52)
 #define SD_CMD_SDIO_RW_EXTENDED                    ((uint8_t)53)
 
+#define SD_CMD53_ARG_Count       0  // 0x001 1   0x002 2   ...   0x1FF 512   0x000 512 byte
+#define SD_CMD53_ARG_Addr        9  // Start Address of I/O register to read or write
+#define SD_CMD53_ARG_AddrInc    26  // 0 Multi byte R/W to fixed address   1 Multi byte R/W to incrementing address
+#define SD_CMD53_ARG_CountUnit  27  // 0 Count in byte   1 Count in block
+#define SD_CMD53_ARG_Function   28  // The number of the function within the I/O card you wish to read or write. Function 0x00 selects the common I/O area (CIA).
+#define SD_CMD53_ARG_nRW        31  // 0 for read   1 for write
+
 
 #define SD_RESP_NO          0   //0 无响应
 #define SD_RESP_32b         2   //2 32位响应
@@ -48,6 +55,15 @@
 #define SD_RES_TIMEOUT      2
 
 
+/* Card Status return by response R1 */
+#define SD_CS_APP_CMD           (1 <<  5)   // The card will expect ACMD
+#define SD_CS_READY_FOR_DATA    (1 <<  8)   // Corresponds to buffer empty signaling on the bus
+#define SD_CS_CURRENT_STATE     (1 <<  9)   // The state of the card when receiving the command. 共 4 位
+#define SD_CS_CARD_ECC_FAILED   (1 << 21)
+#define SD_CS_ILLEGAL_COMMAND   (1 << 22)
+#define SD_CS_CARD_IS_LOCKED    (1 << 25)
+
+
 typedef struct
 {
   __IO uint8_t  CSDStruct;            // CSD structure
@@ -144,4 +160,15 @@ void parseCSD(uint32_t CID_Tab[4]);
 
 uint32_t calcSDCLKDiv(uint32_t freq_sel);
 
+
+enum SDIO_bus_width { SDIO_1bit = 0, SDIO_4bit = 1 };
+
+uint32_t SDIO_IO_Init(uint32_t freq, enum SDIO_bus_width w);
+uint32_t SDIO_IO_ByteWrite(uint8_t func, uint32_t addr, uint8_t data);
+uint32_t SDIO_IO_ByteRead(uint8_t func, uint32_t addr, uint8_t * data);
+uint32_t SDIO_IO_BlockWrite(uint8_t func, uint32_t addr, uint8_t addrInc, uint32_t buff[], uint16_t block_size);
+uint32_t SDIO_IO_BlockRead(uint8_t func, uint32_t addr, uint8_t addrInc, uint32_t buff[], uint16_t block_size);
+uint32_t SDIO_IO_MultiBlockWrite(uint8_t func, uint32_t addr, uint8_t addrInc, uint32_t buff[], uint16_t block_count);
+uint32_t SDIO_IO_MultiBlockRead(uint8_t func, uint32_t addr, uint8_t addrInc, uint32_t buff[], uint16_t block_count);
+
 #endif //__SWM341_SDIO_H__

+ 3 - 3
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.c

@@ -35,9 +35,9 @@ void SDRAM_Init(SDRAM_InitStructure * initStruct)
 
     SYS->CLKEN1 |= (1 << SYS_CLKEN1_SDRAM_Pos);
 
-    SDRAMC->TIM = (initStruct->TimeTRP  << SDRAMC_TIM_TRP_Pos) |
+    SDRAMC->TIM = (initStruct->TimeTRP  << SDRAMC_TIM_TRP_Pos)  |
                   (initStruct->TimeTRCD << SDRAMC_TIM_TRCD_Pos) |
-                  (initStruct->TimeTRFC << SDRAMC_TIM_TRFC_Pos) |
+                  (initStruct->TimeTRC  << SDRAMC_TIM_TRC_Pos)  |
                   ((cyclesPerUs * 200)  << SDRAMC_TIM_T100US_Pos);  // 要求大于100us
 
     SDRAMC->CFG = (initStruct->Size       << SDRAMC_CFG_SIZE_Pos)     |
@@ -54,7 +54,7 @@ void SDRAM_Init(SDRAM_InitStructure * initStruct)
     default:              row_n = 4096; break;
     }
 
-    SDRAMC->T64 = (64*1000 / row_n + 1) * cyclesPerUs;
+    SDRAMC->T64 = (initStruct->RefreshTime * 1000 / row_n + 1) * cyclesPerUs;
 
     SDRAMC->CR = (1 << SDRAMC_CR_PWRON_Pos);
 

+ 23 - 21
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.h

@@ -5,20 +5,22 @@ typedef struct {
     uint8_t Size;               // SDRAM 容量,SDRAM_SIZE_2MB、SDRAM_SIZE_8MB、SDRAM_SIZE_16MB、SDRAM_SIZE_32MB
     uint8_t ClkDiv;             // SDRAM 时钟分频,SDRAM_CLKDIV_1、SDRAM_CLKDIV_2
     uint8_t CASLatency;         // 列地址到有效数据输出间隔,SDRAM_CASLATENCY_2、SDRAM_CASLATENCY_3
+    uint8_t RefreshTime;        // 刷新时间,单位 ms,在这个时间内 SDRAM 必须完成一次整片刷新,通常为 64ms
 
     uint8_t TimeTRP;            // Row precharge delay,Precharge命令到另一个命令间延时
     uint8_t TimeTRCD;           // Row to column delay,行地址到列地址间延时,也即Activate命令到读写命令间延时
-    uint8_t TimeTRFC;           // Refresh Cycle
+    uint8_t TimeTRC;            // Row cycle time, Activate to Activate on same bank
+                                // 若 SDRAM 颗粒除了 tRC,还有 tRFC 或 tRRC 参数,则按照二者中较大的计算 TimeTRC
 } SDRAM_InitStructure;
 
-                                //rowaddr         bankaddr        coladdr
-#define SDRAM_SIZE_2MB      3   //HADDR[20:10]    HADDR[9]        HADDR[8:1]
-#define SDRAM_SIZE_8MB      0   //HADDR[22:11]    HADDR[10:9]     HADDR[8:1]
-#define SDRAM_SIZE_16MB     1   //HADDR[23:12]    HADDR[11:10]    HADDR[9:1]
-#define SDRAM_SIZE_32MB     2   //HADDR[24:12]    HADDR[11:10]    HADDR[9:1]
+                                // rowaddr         bankaddr        coladdr
+#define SDRAM_SIZE_2MB      3   // HADDR[20:10]    HADDR[9]        HADDR[8:1]
+#define SDRAM_SIZE_8MB      0   // HADDR[22:11]    HADDR[10:9]     HADDR[8:1]
+#define SDRAM_SIZE_16MB     1   // HADDR[23:12]    HADDR[11:10]    HADDR[9:1]
+#define SDRAM_SIZE_32MB     2   // HADDR[24:12]    HADDR[11:10]    HADDR[9:1]
 
-#define SDRAM_CLKDIV_1      0
-#define SDRAM_CLKDIV_2      1
+#define SDRAM_CLKDIV_1      0   // 支持的 CPU 频率范围:80MHz--125MHz
+#define SDRAM_CLKDIV_2      1   // 支持的 CPU 频率范围:20MHz--160Mhz
 
 #define SDRAM_CASLATENCY_2  0
 #define SDRAM_CASLATENCY_3  1
@@ -34,19 +36,19 @@ typedef struct {
 #define SDRAM_TRCD_3        2
 #define SDRAM_TRCD_4        3
 
-#define SDRAM_TRFC_4        3
-#define SDRAM_TRFC_5        4
-#define SDRAM_TRFC_6        5
-#define SDRAM_TRFC_7        6
-#define SDRAM_TRFC_8        7
-#define SDRAM_TRFC_9        8
-#define SDRAM_TRFC_10       9
-#define SDRAM_TRFC_11       10
-#define SDRAM_TRFC_12       11
-#define SDRAM_TRFC_13       12
-#define SDRAM_TRFC_14       13
-#define SDRAM_TRFC_15       14
-#define SDRAM_TRFC_16       15
+#define SDRAM_TRC_4         3
+#define SDRAM_TRC_5         4
+#define SDRAM_TRC_6         5
+#define SDRAM_TRC_7         6
+#define SDRAM_TRC_8         7
+#define SDRAM_TRC_9         8
+#define SDRAM_TRC_10        9
+#define SDRAM_TRC_11        10
+#define SDRAM_TRC_12        11
+#define SDRAM_TRC_13        12
+#define SDRAM_TRC_14        13
+#define SDRAM_TRC_15        14
+#define SDRAM_TRC_16        15
 
 
 void SDRAM_Init(SDRAM_InitStructure * initStruct);

+ 82 - 5
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.c

@@ -49,6 +49,12 @@ void SFC_Init(SFC_InitStructure * initStruct)
     SFC->TIM &= ~(SFC_TIM_WIP_CHK_ITV_Msk | SFC_TIM_WIP_CHK_LMT_Msk);
     SFC->TIM |= ((CyclesPerUs / 10) << SFC_TIM_WIP_CHK_ITV_Pos) |   //2048 * (CyclesPerUs / 10) / CyclesPerUs us = 0.2 ms
                 (255 << SFC_TIM_WIP_CHK_LMT_Pos);
+
+    if((initStruct->Width_Read == SFC_RDWIDTH_4) || (initStruct->Width_PageProgram == SFC_PPWIDTH_4))
+    {
+        if(SFC_QuadState() == 0)
+            SFC_QuadSwitch(1);
+    }
 }
 
 /******************************************************************************************************************************************
@@ -66,7 +72,8 @@ uint32_t SFC_ReadJEDEC(void)
     SFC->CMD = SFC_CMD_READ_JEDEC;
 
     SFC->GO = 1;
-    while(SFC->GO);
+    __DSB(); __ISB();
+    while(SFC->GO) __NOP();
 
     return SFC->DATA;
 }
@@ -104,9 +111,10 @@ void SFC_EraseEx(uint32_t addr, uint8_t cmd, uint8_t wait)
                 (1 << SFC_CFG_CMDWREN_Pos) |
                 (type << SFC_CFG_CMDTYPE_Pos);
     SFC->CMD = cmd;
-    SFC->GO = 1;
 
-    for(int i = 0; i < CyclesPerUs; i++) __NOP();   //等待命令发出
+    SFC->GO = 1;
+    __DSB(); __ISB();
+    while(SFC->GO) __NOP();
 
     SFC->CFG &= ~SFC_CFG_WREN_Msk;
 
@@ -135,6 +143,73 @@ void SFC_Write(uint32_t addr, uint32_t buff[], uint32_t cnt)
     SFC->CFG &= ~SFC_CFG_WREN_Msk;
 }
 
+
+#define IOSPI_CS_Low()      GPIO_ClrBit(GPIOD, PIN6); __NOP(); __NOP(); __NOP(); __NOP()
+#define IOSPI_CS_High()     __NOP(); __NOP(); __NOP(); __NOP(); GPIO_SetBit(GPIOD, PIN6)
+#define IOSPI_CLK_Low()     GPIO_ClrBit(GPIOD, PIN5); __NOP(); __NOP()
+#define IOSPI_CLK_High()    __NOP(); __NOP(); GPIO_SetBit(GPIOD, PIN5)
+#define IOSPI_MOSI_Low()    GPIO_ClrBit(GPIOD, PIN8)
+#define IOSPI_MOSI_High()   GPIO_SetBit(GPIOD, PIN8)
+#define IOSPI_MISO_Value()  GPIO_GetBit(GPIOD, PIN7)
+
+static uint8_t IOSPI_ReadWrite(uint8_t data)
+{
+    uint8_t val = 0;
+
+    for(int i = 0; i < 8; i++)
+    {
+        IOSPI_CLK_Low();
+
+        if(data & (1 << (7 - i)))
+            IOSPI_MOSI_High();
+        else
+            IOSPI_MOSI_Low();
+
+        IOSPI_CLK_High();
+
+        val = (val << 1) | IOSPI_MISO_Value();
+    }
+
+    return val;
+}
+
+/******************************************************************************************************************************************
+* 函数名称: SFC_GPIOWrite()
+* 功能说明: SFC 写入较慢,大量写入时,建议用 GPIO 模拟 SPI 写入
+* 输    入: uint32_t addr     数据要写入到Flash中的地址,字对齐
+*           uint32_t buff[]     要写入Flash中的数据
+*           uint32_t cnt        要写的数据的个数,以字为单位,最大64
+* 输    出: 无
+* 注意事项: 执行此函数前需要将相应引脚切到 GPIO 功能,使用完后再次将相应引脚切换回 SFC 功能,以便使用 SFC 擦除、读取功能
+******************************************************************************************************************************************/
+void SFC_GPIOWrite(uint32_t addr, uint32_t buff[], uint32_t cnt)
+{
+    IOSPI_CS_Low();
+    IOSPI_ReadWrite(SFC_CMD_WRITE_ENABLE);
+    IOSPI_CS_High();
+
+    IOSPI_CS_Low();
+    IOSPI_ReadWrite(SFC_CMD_PAGE_PROGRAM);
+    IOSPI_ReadWrite(addr >> 16);
+    IOSPI_ReadWrite(addr >>  8);
+    IOSPI_ReadWrite(addr);
+
+    for(int i = 0; i < cnt * 4; i++)
+    {
+        IOSPI_ReadWrite(((uint8_t *)buff)[i]);
+    }
+    IOSPI_CS_High();
+
+    int busy;
+    do {
+        IOSPI_CS_Low();
+        IOSPI_ReadWrite(SFC_CMD_READ_STATUS_REG1);
+        busy = IOSPI_ReadWrite(0xFF) & (1 << SFC_STATUS_REG_BUSY_Pos);
+        IOSPI_CS_High();
+    } while(busy);
+}
+
+
 /******************************************************************************************************************************************
 * 函数名称: SFC_Read()
 * 功能说明: SPI Flash数据读取
@@ -166,7 +241,8 @@ uint8_t SFC_ReadStatusReg(uint8_t cmd)
     SFC->CMD = cmd;
 
     SFC->GO = 1;
-    while(SFC->GO);
+    __DSB(); __ISB();
+    while(SFC->GO) __NOP();
 
     return SFC->DATA;
 }
@@ -191,7 +267,8 @@ void SFC_WriteStatusReg(uint8_t cmd, uint16_t reg)
     SFC->DATA = reg;
 
     SFC->GO = 1;
-    while(SFC->GO);
+    __DSB(); __ISB();
+    while(SFC->GO) __NOP();
 }
 
 

+ 3 - 0
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.h

@@ -26,6 +26,8 @@ typedef struct {
 
 #define SFC_CMD_READ_JEDEC          0x9F
 #define SFC_CMD_ERASE_CHIP          0x60
+#define SFC_CMD_WRITE_ENABLE        0x06
+#define SFC_CMD_PAGE_PROGRAM        0x02
 #define SFC_CMD_ERASE_SECTOR        0x20
 #define SFC_CMD_ERASE_BLOCK32KB     0x52
 #define SFC_CMD_ERASE_BLOCK64KB     0xD8    //W25Q32
@@ -46,6 +48,7 @@ uint32_t SFC_ReadJEDEC(void);
 void SFC_Erase(uint32_t addr, uint8_t wait);
 void SFC_EraseEx(uint32_t addr, uint8_t cmd, uint8_t wait);
 void SFC_Write(uint32_t addr, uint32_t buff[], uint32_t cnt);
+void SFC_GPIOWrite(uint32_t addr, uint32_t buff[], uint32_t cnt);
 void SFC_Read(uint32_t addr, uint32_t buff[], uint32_t cnt);
 
 

+ 3 - 26
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.c

@@ -57,7 +57,7 @@ void SPI_Init(SPI_TypeDef * SPIx, SPI_InitStructure * initStruct)
         no_sync = 1;
     }
 
-    SPIx->CTRL &= ~(SPI_CTRL_FFS_Msk | SPI_CTRL_CPHA_Msk | SPI_CTRL_CPOL_Msk | SPI_CTRL_SIZE_Msk | SPI_CTRL_MSTR_Msk |
+    SPIx->CTRL &= ~(SPI_CTRL_FFS_Msk | SPI_CTRL_CPHA_Msk | SPI_CTRL_CPOL_Msk | SPI_CTRL_SIZE_Msk | SPI_CTRL_MSTR_Msk | SPI_CTRL_FAST_Msk | SPI_CTRL_NSYNC_Msk |
                     SPI_CTRL_CLKDIV_Msk | SPI_CTRL_SSN_H_Msk | SPI_CTRL_RFTHR_Msk | SPI_CTRL_TFTHR_Msk);
     SPIx->CTRL |= (initStruct->FrameFormat     << SPI_CTRL_FFS_Pos)    |
                   (initStruct->SampleEdge      << SPI_CTRL_CPHA_Pos)   |
@@ -313,12 +313,13 @@ void I2S_Init(SPI_TypeDef * SPIx, I2S_InitStructure * initStruct)
                   (1                           << SPI_CTRL_TFCLR_Pos);
     SPIx->CTRL &= ~(SPI_CTRL_RFCLR_Msk | SPI_CTRL_TFCLR_Msk);
 
-    SPIx->I2SCR &= ~(SPI_I2SCR_MSTR_Msk | SPI_I2SCR_DIEN_Msk | SPI_I2SCR_DOEN_Msk | SPI_I2SCR_FFMT_Msk | SPI_I2SCR_DLEN_Msk | SPI_I2SCR_PCMSYNW_Msk);
+    SPIx->I2SCR &= ~(SPI_I2SCR_MSTR_Msk | SPI_I2SCR_DIEN_Msk | SPI_I2SCR_DOEN_Msk | SPI_I2SCR_FFMT_Msk | SPI_I2SCR_DLEN_Msk | SPI_I2SCR_CHLEN_Msk | SPI_I2SCR_PCMSYNW_Msk);
     SPIx->I2SCR |= ((initStruct->Mode & 0x04 ? 1 : 0) << SPI_I2SCR_MSTR_Pos) |
                    ((initStruct->Mode & 0x02 ? 1 : 0) << SPI_I2SCR_DOEN_Pos) |
                    ((initStruct->Mode & 0x01 ? 1 : 0) << SPI_I2SCR_DIEN_Pos) |
                    ((initStruct->FrameFormat & 0x03)  << SPI_I2SCR_FFMT_Pos) |
                    (initStruct->DataLen               << SPI_I2SCR_DLEN_Pos) |
+                   (initStruct->ChannelLen            << SPI_I2SCR_CHLEN_Pos) |
                    ((initStruct->FrameFormat & 0x04 ? 1 : 0) << SPI_I2SCR_PCMSYNW_Pos);
 
     SPIx->I2SPR &= ~SPI_I2SPR_SCLKDIV_Msk;
@@ -381,27 +382,3 @@ void I2S_Close(SPI_TypeDef * SPIx)
     SPIx->CTRL &= ~SPI_CTRL_EN_Msk;
     SPIx->I2SCR &= ~SPI_I2SCR_EN_Msk;
 }
-
-/******************************************************************************************************************************************
-* 函数名称: I2S_MCLKConfig()
-* 功能说明: I2S MCLK时钟输出配置
-* 输    入: SPI_TypeDef * SPIx        指定要被设置的SPI,有效值包括SPI0、SPI1
-*           uint32_t output_enable  是否输出MCLK时钟
-*           uint32_t mclk_freq      MCLK时钟频率
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void I2S_MCLKConfig(SPI_TypeDef * SPIx, uint32_t output_enable, uint32_t mclk_freq)
-{
-    if(output_enable)
-    {
-        SPIx->I2SPR &= ~SPI_I2SPR_MCLKDIV_Msk;
-        SPIx->I2SPR |= (SystemCoreClock / mclk_freq / 2 - 1) << SPI_I2SPR_MCLKDIV_Pos;
-
-        SPIx->I2SCR |= (1 << SPI_I2SCR_MCLKOE_Pos);
-    }
-    else
-    {
-        SPIx->I2SCR &= ~(1 << SPI_I2SCR_MCLKOE_Pos);
-    }
-}

+ 4 - 2
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.h

@@ -21,7 +21,6 @@ typedef struct {
 #define SPI_FORMAT_SPI          0       //Motorola SPI 格式
 #define SPI_FORMAT_TI_SSI       1       //TI SSI 格式
 #define SPI_FORMAT_I2S          2
-#define SPI_FORMAT_FLASH        3       //SPI Flash 四线读模式
 
 #define SPI_FIRST_EDGE          0       //第一个时钟沿开始采样
 #define SPI_SECOND_EDGE         1       //第二个时钟沿开始采样
@@ -78,6 +77,7 @@ uint32_t SPI_INTStat(SPI_TypeDef * SPIx, uint32_t it);  //中断状态查询
 typedef struct {
     uint8_t  Mode;          //I2S_MASTER_TX、I2S_MASTER_RX、I2S_MASTER_TX_RX、I2S_SLAVE_TX、I2S_SLAVE_RX、I2S_SLAVE_TX_RX
     uint8_t  FrameFormat;   //I2S_I2S_PHILIPS、I2S_MSB_JUSTIFIED、I2S_PCM_SHORT、I2S_PCM_LONG0、I2S_PCM_LONG1
+    uint8_t  ChannelLen;    //I2S_CHNNLEN_16、I2S_CHNNLEN_32
     uint8_t  DataLen;       //I2S_DATALEN_8、I2S_DATALEN_16、I2S_DATALEN_24、I2S_DATALEN_32
     uint32_t ClkFreq;       //I2S_SCLK Frequency
 
@@ -101,6 +101,9 @@ typedef struct {
 #define I2S_PCM_LONG0       3   //PCM Long Mode Sync Width 1 SCLK period
 #define I2S_PCM_LONG1       4   //PCM Long Mode Sync Width 1 Data Length
 
+#define I2S_CHNNLEN_16      0
+#define I2S_CHNNLEN_32      1
+
 #define I2S_DATALEN_8       0
 #define I2S_DATALEN_16      1
 #define I2S_DATALEN_24      2
@@ -109,7 +112,6 @@ typedef struct {
 void I2S_Init(SPI_TypeDef * SPIx, I2S_InitStructure * initStruct);      //I2S初始化
 void I2S_Open(SPI_TypeDef * SPIx);                                      //I2S打开,允许收发
 void I2S_Close(SPI_TypeDef * SPIx);                                     //I2S关闭,禁止收发
-void I2S_MCLKConfig(SPI_TypeDef * SPIx, uint32_t output_enable, uint32_t mclk_freq);
 
 
 #endif //__SWM341_SPI_H__

+ 28 - 115
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.c

@@ -67,7 +67,8 @@ void UART_Init(UART_TypeDef * UARTx, UART_InitStructure * initStruct)
                    (initStruct->TXThreshold << UART_FIFO_TXTHR_Pos);
 
     UARTx->TOCR &= ~UART_TOCR_TIME_Msk;
-    UARTx->TOCR |= (initStruct->TimeoutTime << UART_TOCR_TIME_Pos);
+    UARTx->TOCR |= (1 << UART_TOCR_MODE_Pos) |
+                   (initStruct->TimeoutTime << UART_TOCR_TIME_Pos);
 
     UARTx->CTRL &= ~(UART_CTRL_RXIE_Msk | UART_CTRL_TXIE_Msk | UART_CTRL_TOIE_Msk);
     UARTx->CTRL |= (initStruct->RXThresholdIEn << UART_CTRL_RXIE_Pos) |
@@ -369,7 +370,7 @@ uint32_t UART_LINIsGenerated(UART_TypeDef * UARTx)
 ******************************************************************************************************************************************/
 void UART_ABRStart(UART_TypeDef * UARTx, uint32_t detectChar)
 {
-    uint32_t bits;
+    uint32_t bits = 0;
 
     if((detectChar == 0xFF) || (detectChar == 0x1FF))      bits = 0;
     else if((detectChar == 0xFE) || (detectChar == 0x1FE)) bits = 1;
@@ -406,145 +407,57 @@ uint32_t UART_ABRIsDone(UART_TypeDef * UARTx)
 }
 
 /******************************************************************************************************************************************
-* 函数名称: UART_INTRXThresholdEn()
-* 功能说明: 当RX FIFO中数据个数 >= RXThreshold时 触发中断
+* 函数名称: UART_INTEn()
+* 功能说明: 中断使能
 * 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
+*           uint32_t it             interrupt type,有效值有 UART_IT_RX_THR、UART_IT_RX_TOUT、UART_IT_TX_THR、UART_IT_TX_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void UART_INTRXThresholdEn(UART_TypeDef * UARTx)
+void UART_INTEn(UART_TypeDef * UARTx, uint32_t it)
 {
-    UARTx->CTRL |= (0x01 << UART_CTRL_RXIE_Pos);
+    UARTx->CTRL |= it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: UART_INTRXThresholdDis()
-* 功能说明: 当RX FIFO中数据个数 >= RXThreshold时 不触发中断
+* 函数名称: UART_INTDis()
+* 功能说明: 中断禁止
 * 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
+*           uint32_t it             interrupt type,有效值有 UART_IT_RX_THR、UART_IT_RX_TOUT、UART_IT_TX_THR、UART_IT_TX_DONE 及其“或”
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void UART_INTRXThresholdDis(UART_TypeDef * UARTx)
+void UART_INTDis(UART_TypeDef * UARTx, uint32_t it)
 {
-    UARTx->CTRL &= ~(0x01 << UART_CTRL_RXIE_Pos);
+    UARTx->CTRL &= ~it;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: UART_INTRXThresholdStat()
-* 功能说明: 是否RX FIFO中数据个数 >= RXThreshold
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: uint32_t              1 RX FIFO中数据个数 >= RXThreshold       0 RX FIFO中数据个数 < RXThreshold
-* 注意事项: RXIF = RXTHRF & RXIE
-******************************************************************************************************************************************/
-uint32_t UART_INTRXThresholdStat(UART_TypeDef * UARTx)
-{
-    return (UARTx->BAUD & UART_BAUD_RXIF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXThresholdEn()
-* 功能说明: 当TX FIFO中数据个数 <= TXThreshold时 触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTXThresholdEn(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL |= (0x01 << UART_CTRL_TXIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXThresholdDis()
-* 功能说明: 当TX FIFO中数据个数 <= TXThreshold时 不触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTXThresholdDis(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL &= ~(0x01 << UART_CTRL_TXIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXThresholdStat()
-* 功能说明: 是否TX FIFO中数据个数 <= TXThreshold
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: uint32_t              1 TX FIFO中数据个数 <= TXThreshold       0 TX FIFO中数据个数 > TXThreshold
-* 注意事项: TXIF = TXTHRF & TXIE
-******************************************************************************************************************************************/
-uint32_t UART_INTTXThresholdStat(UART_TypeDef * UARTx)
-{
-    return (UARTx->BAUD & UART_BAUD_TXIF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTimeoutEn()
-* 功能说明: 接收发生超时时 触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTimeoutEn(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL |= (0x01 << UART_CTRL_TOIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTimeoutDis()
-* 功能说明: 接收发生超时时 不触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTimeoutDis(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL &= ~(0x01 << UART_CTRL_TOIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTimeoutStat()
-* 功能说明: 是否发生了接收超时,即超过 TimeoutTime/(Baudrate/10) 秒没有在RX线上接收到数据时触发中断
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: uint32_t              1 发生了接收超时       0 未发生接收超时
-* 注意事项: 无
-******************************************************************************************************************************************/
-uint32_t UART_INTTimeoutStat(UART_TypeDef * UARTx)
-{
-    return (UARTx->BAUD & UART_BAUD_TOIF_Msk) ? 1 : 0;
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXDoneEn()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断使能
-* 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: 无
-* 注意事项: 无
-******************************************************************************************************************************************/
-void UART_INTTXDoneEn(UART_TypeDef * UARTx)
-{
-    UARTx->CTRL |= (0x01 << UART_CTRL_TXDOIE_Pos);
-}
-
-/******************************************************************************************************************************************
-* 函数名称: UART_INTTXDoneDis()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断禁止
+* 函数名称: UART_INTClr()
+* 功能说明: 中断标志清除
 * 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
+*           uint32_t it             interrupt type,有效值有 UART_IT_RX_TOUT
 * 输    出: 无
 * 注意事项: 无
 ******************************************************************************************************************************************/
-void UART_INTTXDoneDis(UART_TypeDef * UARTx)
+void UART_INTClr(UART_TypeDef * UARTx, uint32_t it)
 {
-    UARTx->CTRL &= ~(0x01 << UART_CTRL_TXDOIE_Pos);
+    if(it & UART_IT_RX_TOUT)
+        UARTx->TOCR |= UART_TOCR_IFCLR_Msk;
 }
 
 /******************************************************************************************************************************************
-* 函数名称: UART_INTTXDoneStat()
-* 功能说明: 发送FIFO空且发送移位寄存器空中断状态
+* 函数名称: UART_INTStat()
+* 功能说明: 中断状态查询
 * 输    入: UART_TypeDef * UARTx  指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3
-* 输    出: uint32_t              1 发送FIFO空且发送移位寄存器空      0 发送FIFO或发送移位寄存器未空
+*           uint32_t it             interrupt type,有效值有 UART_IT_RX_THR、UART_IT_RX_TOUT、UART_IT_TX_THR、UART_IT_TX_DONE 及其“或”
+* 输    出: uint32_t              1 中断已发生    0 中断未发生
 * 注意事项: 无
 ******************************************************************************************************************************************/
-uint32_t UART_INTTXDoneStat(UART_TypeDef * UARTx)
+uint32_t UART_INTStat(UART_TypeDef * UARTx, uint32_t it)
 {
-    return (UARTx->BAUD & UART_BAUD_TXDOIF_Msk) ? 1 : 0;
+    return (((it & UART_IT_RX_THR)  && (UARTx->BAUD & UART_BAUD_RXIF_Msk)) ||
+            ((it & UART_IT_RX_TOUT) && (UARTx->BAUD & UART_BAUD_TOIF_Msk)) ||
+            ((it & UART_IT_TX_THR)  && (UARTx->BAUD & UART_BAUD_TXIF_Msk)) ||
+            ((it & UART_IT_TX_DONE) && (UARTx->BAUD & UART_BAUD_TXDOIF_Msk)));
 }

+ 12 - 13
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.h

@@ -46,6 +46,14 @@ typedef struct {
 #define UART_ERR_NOISE      3
 
 
+/* Interrupt Type */
+#define UART_IT_RX_THR      (1 << UART_CTRL_RXIE_Pos)   //RX FIFO Threshold, RX FIFO中数据个数 >  RXThreshold
+#define UART_IT_RX_TOUT     (1 << UART_CTRL_TOIE_Pos)   //RX Timeout, 超过 TimeoutTime/(Baudrate/10) 秒没有在RX线上接收到数据
+#define UART_IT_TX_THR      (1 << UART_CTRL_TXIE_Pos)   //TX FIFO Threshold, TX FIFO中数据个数 <= TXThreshold
+#define UART_IT_TX_DONE     (1 << UART_CTRL_TXDOIE_Pos) //TX Done, 发送FIFO空且发送发送移位寄存器已将最后一位发送出去
+
+
+
 void UART_Init(UART_TypeDef * UARTx, UART_InitStructure * initStruct);  //UART串口初始化
 void UART_Open(UART_TypeDef * UARTx);
 void UART_Close(UART_TypeDef * UARTx);
@@ -75,19 +83,10 @@ uint32_t UART_LINIsGenerated(UART_TypeDef * UARTx);
 void UART_ABRStart(UART_TypeDef * UARTx, uint32_t detectChar);
 uint32_t UART_ABRIsDone(UART_TypeDef * UARTx);
 
+void UART_INTEn(UART_TypeDef * UARTx, uint32_t it);
+void UART_INTDis(UART_TypeDef * UARTx, uint32_t it);
+void UART_INTClr(UART_TypeDef * UARTx, uint32_t it);
+uint32_t UART_INTStat(UART_TypeDef * UARTx, uint32_t it);
 
-void UART_INTRXThresholdEn(UART_TypeDef * UARTx);
-void UART_INTRXThresholdDis(UART_TypeDef * UARTx);
-uint32_t UART_INTRXThresholdStat(UART_TypeDef * UARTx);
-void UART_INTTXThresholdEn(UART_TypeDef * UARTx);
-void UART_INTTXThresholdDis(UART_TypeDef * UARTx);
-uint32_t UART_INTTXThresholdStat(UART_TypeDef * UARTx);
-void UART_INTTimeoutEn(UART_TypeDef * UARTx);
-void UART_INTTimeoutDis(UART_TypeDef * UARTx);
-uint32_t UART_INTTimeoutStat(UART_TypeDef * UARTx);
-
-void UART_INTTXDoneEn(UART_TypeDef * UARTx);
-void UART_INTTXDoneDis(UART_TypeDef * UARTx);
-uint32_t UART_INTTXDoneStat(UART_TypeDef * UARTx);
 
 #endif //__SWM341_UART_H__

+ 6 - 0
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usb.h

@@ -53,6 +53,7 @@ typedef struct {
 #define USB_DESC_OTG                0x09
 #define USB_DESC_BOS                0x0F
 #define USB_DESC_CAPABILITY         0x10
+#define USB_DESC_CS_INTERFACE       0x24    // Class Specific Interface
 
 /* USB HID Descriptor Type */
 #define USB_DESC_HID                0x21
@@ -90,12 +91,17 @@ typedef struct {
 #define USB_CDC_CTRL_CLASS          0x02    // for Interface
 #define USB_CDC_DATA_CLASS          0x0A    // for Interface
 #define USB_HID_CLASS               0x03    // for Interface
+#define USB_MTP_CLASS               0x06    // for Interface
 #define USB_MSC_CLASS               0x08    // for Interface
+#define USB_UVC_CLASS               0x0E    // for Interface
 
 
 /* SubClass */
 #define USB_CDC_ACM                 0x02    // Abstract Control Model
 #define USB_HID_BOOT                0x01
+#define USB_UVC_VIDEOCONTROL                0x01
+#define USB_UVC_VIDEOSTREAMING              0x02
+#define USB_UVC_VIDEO_INTERFACE_COLLECTION  0x03
 
 /* Protocol */
 #define USB_CDC_ATCMD               0x01    // AT Commands defined by ITU-T V.250

+ 2 - 1
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usbh.c

@@ -40,6 +40,7 @@ void USBH_HW_Init(void)
     SYS->USBCR |= (1 << SYS_USBCR_RST48M_Pos); __DSB();
     SYS->USBCR |= (1 << SYS_USBCR_RST12M_Pos); __DSB();
     SYS->USBCR |= (1 << SYS_USBCR_RSTPLL_Pos); __DSB();
+    for(int i = 0; i < CyclesPerUs; i++) __NOP();
 
     SYS->USBCR &= ~SYS_USBCR_ROLE_Msk;
     SYS->USBCR |= (2 << SYS_USBCR_ROLE_Pos);
@@ -279,7 +280,7 @@ uint32_t USBH_ReadRxBuffer(uint8_t *buff, uint32_t size)
     if(size > real_size)
         size = real_size;
 
-    memcpy(buff, (uint8_t *)USBH->RXBUF, size);
+    USBD_memcpy(buff, (uint8_t *)USBH->RXBUF, size);
 
     return size;
 }

+ 26 - 4
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.c

@@ -29,14 +29,12 @@
 *           uint32_t int_period     中断周期,取值1--2^16,单位1/1024秒,取值0表示关闭WDT中断功能
 *           uint32_t rst_period     复位周期,取值1--2^16,单位1/1024秒,取值0表示关闭WDT复位功能
 * 输    出: 无
-* 注意事项: 
+* 注意事项: 此函数只能在芯片上电后调用一次,若需要重新配置 WDT,请调用 WDT_ReInit()
 ******************************************************************************************************************************************/
 void WDT_Init(WDT_TypeDef * WDTx, uint32_t int_period, uint32_t rst_period)
 {
     SYS->CLKEN0 |= (1 << SYS_CLKEN0_WDT_Pos);
 
-    WDT_Stop(WDTx);     //设置前先关闭
-
     WDTx->CR &= ~WDT_CR_CKDIV_Msk;
     WDTx->CR |= (4 << WDT_CR_CKDIV_Pos);    // 对时钟源 32 分频
 
@@ -70,6 +68,29 @@ void WDT_Init(WDT_TypeDef * WDTx, uint32_t int_period, uint32_t rst_period)
     }
 }
 
+/******************************************************************************************************************************************
+* 函数名称: WDT_ReInit()
+* 功能说明: WDT看门狗重新初始化
+* 输    入: 同 WDT_Init()
+* 输    出: 无
+* 注意事项: 执行 WDT_ReInit() 前请不要执行 WDT_Stop(),因为 WDT 停止状态下无法清零内部计数器
+******************************************************************************************************************************************/
+void WDT_ReInit(WDT_TypeDef * WDTx, uint32_t int_period, uint32_t rst_period)
+{
+    int i;
+
+    /* WDT 已经在运行中,若新设置的 rst_period 比当前计数器值还小,WDT 需要计数到 2^16 溢出返回 0 才能触发中断和复位,
+       这里执行一下喂狗,保证计数器从零重新计数,避免上述问题 */
+    WDT_Feed(WDTx);
+
+    /* 等待 WDT 内部完成喂狗操作,计数器清零 */
+    for(i = 0; i < CyclesPerUs * 300 / 4; i++) __NOP();
+
+    WDT_Stop(WDTx);
+
+    WDT_Init(WDTx, int_period, rst_period);
+}
+
 /******************************************************************************************************************************************
 * 函数名称: WDT_Start()
 * 功能说明: 启动指定WDT,开始倒计时
@@ -103,7 +124,8 @@ void WDT_Stop(WDT_TypeDef * WDTx)
 ******************************************************************************************************************************************/
 void WDT_Feed(WDT_TypeDef * WDTx)
 {
-    WDTx->FEED = 0x55;
+    if(WDTx->CR & WDT_CR_EN_Msk) // WDT 停止状态下,不执行喂狗
+        WDTx->FEED = 0x55;
 }
 
 /******************************************************************************************************************************************

+ 1 - 0
bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.h

@@ -2,6 +2,7 @@
 #define __SWM341_WDT_H__
 
 void WDT_Init(WDT_TypeDef * WDTx, uint32_t int_period, uint32_t rst_period);
+void WDT_ReInit(WDT_TypeDef * WDTx, uint32_t int_period, uint32_t rst_period);
 void WDT_Start(WDT_TypeDef * WDTx);         //启动指定WDT,开始倒计时
 void WDT_Stop(WDT_TypeDef * WDTx);          //关闭指定WDT,停止倒计时
 

+ 119 - 2
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.c

@@ -18,6 +18,7 @@
 *
 * COPYRIGHT 2012 Synwit Technology
 *******************************************************************************************************************************************/
+#include <string.h>
 #include "SWM341.h"
 #include "usbh_hid_core.h"
 #include "usbh_hid_keybd.h"
@@ -26,17 +27,133 @@
 USBH_HID_cb_t USBH_HID_KeyBD_cb =
 {
     USBH_HID_KeyBD_Init,
-    USBH_HID_KeyBd_Decode
+    USBH_HID_KeyBD_Decode
 };
 
 
+static const uint8_t HID_KEYBRD_Codes[] = {
+      0,   0,   0,   0,  31,  50,  48,  33,  19,  34,  35,  36,  24,  37,  38,  39,
+     52,  51,  25,  26,  17,  20,  32,  21,  23,  49,  18,  47,  22,  46,   2,   3,
+      4,   5,   6,   7,   8,   9,  10,  11,  43, 110,  15,  16,  61,  12,  13,  27,
+     28,  29,  42,  40,  41,   1,  53,  54,  55,  30, 112, 113, 114, 115, 116, 117,
+    118, 119, 120, 121, 122, 123, 124, 125, 126,  75,  80,  85,  76,  81,  86,  89,
+     79,  84,  83,  90,  95, 100, 105, 106, 108,  93,  98, 103,  92,  97, 102,  91,
+     96, 101,  99, 104,  45, 129,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0, 107,   0,  56,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     58,  44,  60, 127,  64,  57,  62, 128,
+};
+
+static const uint8_t HID_KEYBRD_Key[] = {
+    '\0', '`',  '1',  '2',  '3',  '4',  '5',  '6',  '7',  '8',
+    '9',  '0',  '-',  '=',  '\0', '\r', '\t', 'q',  'w',  'e',
+    'r',  't',  'y',  'u',  'i',  'o',  'p',  '[',  ']',  '\\',
+    '\0', 'a',  's',  'd',  'f',  'g',  'h',  'j',  'k',  'l',
+    ';',  '\'', '\0', '\n', '\0', '\0', 'z',  'x',  'c',  'v',
+    'b',  'n',  'm',  ',',  '.',  '/',  '\0', '\0', '\0', '\0',
+    '\0', ' ',  '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\r', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '7',  '4',  '1',  '\0', '/',  '8',  '5',  '2',  '0',
+    '*',  '9',  '6',  '3',  '.',  '-',  '+',  '\0', '\n', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
+};
+
+static const uint8_t HID_KEYBRD_ShiftKey[] = {
+    '\0', '~',  '!',  '@',  '#',  '$',  '%',  '^',  '&',  '*',
+    '(',  ')',  '_',  '+',  '\0', '\0', '\0', 'Q',  'W',  'E',
+    'R',  'T',  'Y',  'U',  'I',  'O',  'P',  '{',  '}',  '|',
+    '\0', 'A',  'S',  'D',  'F',  'G',  'H',  'J',  'K',  'L',
+    ':',  '"',  '\0', '\n', '\0', '\0', 'Z',  'X',  'C',  'V',
+    'B',  'N',  'M',  '<',  '>',  '?',  '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
+};
+
+
+static uint8_t keys_last[6];
+static uint8_t nbr_keys_last;
 
 
 void USBH_HID_KeyBD_Init(void)
 {
+    nbr_keys_last = 0;
+    memset(keys_last, 0x00, 6);
+}
+
+
+void USBH_HID_KeyBD_Decode(uint8_t *pbuf)
+{
+    char key;
+    uint8_t i, j;
+    uint8_t keys[6];
+    uint8_t keys_new[6];
+    uint8_t nbr_keys;
+    uint8_t nbr_keys_new;
+
+    for(i = 2; i < 8; i++)
+    {
+        if((pbuf[i] == 0x01) || (pbuf[i] == 0x02) || (pbuf[i] == 0x03))
+            return;
+    }
+
+    nbr_keys     = 0;
+    nbr_keys_new = 0;
+    for(i = 2; i < 8; i++)
+    {
+        if(pbuf[i] != 0x00)
+        {
+            keys[nbr_keys++] = pbuf[i];
+
+            for(j = 0; j < nbr_keys_last; j++)
+            {
+                if(pbuf[i] == keys_last[j])
+                    break;
+            }
+
+            if(j == nbr_keys_last)  // 遍历到了最后,说明 pbuf[i] 不在 keys_last 中,是新按下的
+                keys_new[nbr_keys_new++] = pbuf[i];
+        }
+    }
+
+    if(nbr_keys_new == 1)
+    {
+        if((pbuf[0] & KBD_LEFT_SHIFT) || (pbuf[0] & KBD_RIGHT_SHIFT))
+        {
+            key = HID_KEYBRD_ShiftKey[HID_KEYBRD_Codes[keys_new[0]]];
+        }
+        else
+        {
+            key = HID_KEYBRD_Key[HID_KEYBRD_Codes[keys_new[0]]];
+        }
+
+        USBH_HID_KeyBD_Handle(pbuf[0], key);    // call user process handle
+    }
+
+    memcpy(keys_last, keys, 6);
+    nbr_keys_last = nbr_keys;
 }
 
 
-void USBH_HID_KeyBd_Decode(uint8_t *pbuf)
+__attribute__((weak))
+void USBH_HID_KeyBD_Handle(uint8_t ctrl, char key)
 {
+    if((ctrl & KBD_LEFT_CTRL) | (ctrl & KBD_RIGHT_CTRL))
+        printf("Ctrl-");
+
+    if((ctrl & KBD_LEFT_ALT) | (ctrl & KBD_RIGHT_ALT))
+        printf("Alt-");
+
+    printf("%c\r\n", key);
 }

+ 14 - 1
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.h

@@ -4,11 +4,24 @@
 #include <stdint.h>
 
 
+#define KBD_LEFT_CTRL       0x01
+#define KBD_LEFT_SHIFT      0x02
+#define KBD_LEFT_ALT        0x04
+#define KBD_LEFT_CMD        0x08
+#define KBD_RIGHT_CTRL      0x10
+#define KBD_RIGHT_SHIFT     0x20
+#define KBD_RIGHT_ALT       0x40
+#define KBD_RIGHT_CMD       0x80
+
+
 extern USBH_HID_cb_t USBH_HID_KeyBD_cb;
 
 
 void USBH_HID_KeyBD_Init(void);
-void USBH_HID_KeyBd_Decode(uint8_t *pbuf);
+void USBH_HID_KeyBD_Decode(uint8_t *pbuf);
+
+__attribute__((weak))
+void USBH_HID_KeyBD_Handle(uint8_t ctrl, char key);
 
 
 #endif // __USBH_HID_KEYBD_H__

+ 1366 - 0
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.c

@@ -0,0 +1,1366 @@
+/******************************************************************************************************************************************
+* 文件名称: usbh_mtp.c
+* 功能说明: This file is the MTP Layer Handlers for USB Host MTP class.
+* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
+* 注意事项:
+* 版本日期: V1.1.0      2020年11月3日
+* 升级记录:
+*
+*
+*******************************************************************************************************************************************
+* @attention
+*
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
+* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
+* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
+* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
+* -ECTION WITH THEIR PRODUCTS.
+*
+* COPYRIGHT 2012 Synwit Technology
+*******************************************************************************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+#include "SWM341.h"
+#include "usbh_core.h"
+#include "usbh_mtp.h"
+
+
+static USBH_Status USBH_MTP_Init(USBH_Info_t *phost);
+static void        USBH_MTP_DeInit(USBH_Info_t *phost);
+static USBH_Status USBH_MTP_Request(USBH_Info_t *phost);
+static USBH_Status USBH_MTP_Process(USBH_Info_t *phost);
+
+USBH_Class_cb_t USBH_MTP_cb =
+{
+    USBH_MTP_Init,
+    USBH_MTP_DeInit,
+    USBH_MTP_Request,
+    USBH_MTP_Process,
+};
+
+
+USBH_MTP_Info_t USBH_MTP_Info;
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_Init()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+static USBH_Status USBH_MTP_Init(USBH_Info_t *phost)
+{
+    USB_EpDesc_t *pEpIn, *pEpOut, *pEpNotify;
+
+    for(int i = 0; i < phost->Device.Cfg_Desc.bNumInterfaces; i++)
+    {
+        if(((phost->Device.Intf_Desc[i].bInterfaceClass == USB_MTP_CLASS) && (phost->Device.Intf_Desc[i].bNumEndpoints == 3)) ||
+           ((phost->Device.Intf_Desc[i].bInterfaceClass == 0xFF)          && (phost->Device.Intf_Desc[i].bNumEndpoints == 3)))
+        {
+#define EpVerify(ep, dir, type)  (((phost->Device.Ep_Desc[i][ep].bEndpointAddress & USB_EP_IN) == dir) && \
+                                  ((phost->Device.Ep_Desc[i][ep].bmAttributes & USB_EP_INT) == type))
+            if(EpVerify(0, USB_EP_IN, USB_EP_INT) && EpVerify(1, USB_EP_IN, USB_EP_BULK) && EpVerify(2, USB_EP_OUT, USB_EP_BULK))
+            {
+                pEpNotify = &phost->Device.Ep_Desc[i][0];
+                pEpIn     = &phost->Device.Ep_Desc[i][1];
+                pEpOut    = &phost->Device.Ep_Desc[i][2];
+            }
+            else if(EpVerify(0, USB_EP_IN, USB_EP_INT) && EpVerify(2, USB_EP_IN, USB_EP_BULK) && EpVerify(1, USB_EP_OUT, USB_EP_BULK))
+            {
+                pEpNotify = &phost->Device.Ep_Desc[i][0];
+                pEpIn     = &phost->Device.Ep_Desc[i][2];
+                pEpOut    = &phost->Device.Ep_Desc[i][1];
+            }
+            else if(EpVerify(1, USB_EP_IN, USB_EP_INT) && EpVerify(0, USB_EP_IN, USB_EP_BULK) && EpVerify(2, USB_EP_OUT, USB_EP_BULK))
+            {
+                pEpNotify = &phost->Device.Ep_Desc[i][1];
+                pEpIn     = &phost->Device.Ep_Desc[i][0];
+                pEpOut    = &phost->Device.Ep_Desc[i][2];
+            }
+            else if(EpVerify(1, USB_EP_IN, USB_EP_INT) && EpVerify(2, USB_EP_IN, USB_EP_BULK) && EpVerify(0, USB_EP_OUT, USB_EP_BULK))
+            {
+                pEpNotify = &phost->Device.Ep_Desc[i][1];
+                pEpIn     = &phost->Device.Ep_Desc[i][2];
+                pEpOut    = &phost->Device.Ep_Desc[i][0];
+            }
+            else if(EpVerify(2, USB_EP_IN, USB_EP_INT) && EpVerify(0, USB_EP_IN, USB_EP_BULK) && EpVerify(1, USB_EP_OUT, USB_EP_BULK))
+            {
+                pEpNotify = &phost->Device.Ep_Desc[i][2];
+                pEpIn     = &phost->Device.Ep_Desc[i][0];
+                pEpOut    = &phost->Device.Ep_Desc[i][1];
+            }
+            else if(EpVerify(2, USB_EP_IN, USB_EP_INT) && EpVerify(1, USB_EP_IN, USB_EP_BULK) && EpVerify(0, USB_EP_OUT, USB_EP_BULK))
+            {
+                pEpNotify = &phost->Device.Ep_Desc[i][2];
+                pEpIn     = &phost->Device.Ep_Desc[i][1];
+                pEpOut    = &phost->Device.Ep_Desc[i][0];
+            }
+            else
+            {
+                continue;
+            }
+
+            USBH_MTP_Info.InEp         = pEpIn->bEndpointAddress;
+            USBH_MTP_Info.InEpSize     = pEpIn->wMaxPacketSize;
+            USBH_MTP_Info.OutEp        = pEpOut->bEndpointAddress;
+            USBH_MTP_Info.OutEpSize    = pEpOut->wMaxPacketSize;
+            USBH_MTP_Info.NotifyEp     = pEpNotify->bEndpointAddress;
+            USBH_MTP_Info.NotifyEpSize = pEpNotify->wMaxPacketSize;
+
+            USBH_MTP_Info.events.poll  = pEpNotify->bInterval;
+
+            SW_LOG_INFO("InEp: %x, InEpSize: %d", pEpIn->bEndpointAddress, pEpIn->wMaxPacketSize);
+            SW_LOG_INFO("OutEp: %x, OutEpSize: %d", pEpOut->bEndpointAddress, pEpOut->wMaxPacketSize);
+            SW_LOG_INFO("NotifyEp: %x, NotifyEpSize: %d, NotifyInterval: %d", pEpNotify->bEndpointAddress, pEpNotify->wMaxPacketSize, pEpNotify->bInterval);
+
+            USBH_MTP_DeInit(phost);
+
+            return USBH_OK;
+        }
+        else
+        {
+            continue;
+        }
+    }
+
+    if(phost->usr_cb->DeviceNotSupported)
+        phost->usr_cb->DeviceNotSupported();
+
+    return USBH_NOT_SUPPORTED;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_DeInit()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+static void USBH_MTP_DeInit(USBH_Info_t *phost)
+{
+    USBH_MTP_Info.is_ready = 0;
+
+    USBH_MTP_Info.InEpDATAX = 0;
+    USBH_MTP_Info.OutEpDATAX = 0;
+    USBH_MTP_Info.NotifyEpDATAX = 0;
+
+    USBH_MTP_Info.XferState = USBH_MTP_XFER_IDLE;
+    USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+
+    USBH_MTP_Info.state = USBH_MTP_GETDEVICEINFO;
+    USBH_MTP_Info.stateReq = USBH_MTP_IDLE;
+
+    SW_LOG_INFO("USBH_MTP_DeInit");
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_Request()
+* 功能说明: Used for handling Standard requests for MTP class.
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+static USBH_Status USBH_MTP_Request(USBH_Info_t *phost)
+{
+    return USBH_OK;
+}
+
+
+void USBH_MTP_XferProcess(USBH_Info_t *phost);
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_Process()
+* 功能说明: Used for managing state machine for MTP data transfers.
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+static USBH_Status USBH_MTP_Process(USBH_Info_t *phost)
+{
+    USBH_Resp resp;
+    USBH_Status status = USBH_BUSY;
+
+    if((USBH_MTP_Info.state != USBH_MTP_EVENT_WAIT) &&
+       (USBH_MTP_Info.state != USBH_MTP_EVENT_CHECK))
+    {
+        if(USBH_MTP_Info.stateReq != USBH_MTP_IDLE)
+        {
+            USBH_MTP_Info.stateBkp = USBH_MTP_Info.state;
+            USBH_MTP_Info.state = USBH_MTP_Info.stateReq;
+
+            USBH_MTP_Info.stateReq = USBH_MTP_IDLE;
+        }
+    }
+
+    switch(USBH_MTP_Info.state)
+    {
+    case USBH_MTP_GETDEVICEINFO:
+        status = USBH_MTP_GetDeviceInfo(phost, &USBH_MTP_Info.devinfo);
+        if(status == USBH_OK)
+        {
+            SW_LOG_INFO("MTP Device Information");
+            SW_LOG_INFO("  Standard version : %x", USBH_MTP_Info.devinfo.StandardVersion);
+            SW_LOG_INFO("  Vendor ExtID : %s",     USBH_MTP_Info.devinfo.VendorExtensionID == 6 ? "MTP" : "NOT SUPPORTED");
+            SW_LOG_INFO("  Functional mode : %s",  USBH_MTP_Info.devinfo.FunctionalMode == 0 ? "Standard" : "Vendor");
+            SW_LOG_INFO("  Number of Supported Operation(s) : %d", USBH_MTP_Info.devinfo.OperationsSupportedNbr);
+            SW_LOG_INFO("  Number of Supported Events(s) : %d",    USBH_MTP_Info.devinfo.EventsSupportedNbr);
+            SW_LOG_INFO("  Number of Supported Proprieties : %d",  USBH_MTP_Info.devinfo.DevicePropertiesSupportedNbr);
+            SW_LOG_INFO("  Manufacturer : %s",   USBH_MTP_Info.devinfo.Manufacturer);
+            SW_LOG_INFO("  Model : %s",          USBH_MTP_Info.devinfo.Model);
+            SW_LOG_INFO("  Device version : %s", USBH_MTP_Info.devinfo.DeviceVersion);
+            SW_LOG_INFO("  Serial number : %s",  USBH_MTP_Info.devinfo.SerialNumber);
+
+            USBH_MTP_Info.state = USBH_MTP_OPENSESSION;
+        }
+        break;
+
+    case USBH_MTP_OPENSESSION:
+        status = USBH_MTP_OpenSession(phost, 1);
+        if(status == USBH_OK)
+        {
+            SW_LOG_INFO("MTP Session #1 Opened");
+
+            USBH_MTP_Info.state = USBH_MTP_GETSTORAGEIDS;
+        }
+        break;
+
+    case USBH_MTP_GETSTORAGEIDS:
+        status = USBH_MTP_GetStorageIds(phost, &USBH_MTP_Info.storids);
+        if(status == USBH_OK)
+        {
+            SW_LOG_INFO("Number of storage ID items : %d", USBH_MTP_Info.storids.n);
+            for(int i  = 0; i < USBH_MTP_Info.storids.n; i++)
+            {
+                SW_LOG_INFO("storage#%d ID : %x", i, USBH_MTP_Info.storids.Storage[i]);
+            }
+
+            USBH_MTP_Info.CurrentStorage = 0;
+            if(USBH_MTP_Info.storids.n)
+                USBH_MTP_Info.state = USBH_MTP_GETSTORAGEINFO;
+        }
+        break;
+
+    case USBH_MTP_GETSTORAGEINFO:
+        status = USBH_MTP_GetStorageInfo(phost, USBH_MTP_Info.storids.Storage[USBH_MTP_Info.CurrentStorage],
+                                               &USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage]);
+        if(status == USBH_OK)
+        {
+            SW_LOG_INFO("Volume#%u: %s   [%s]", USBH_MTP_Info.CurrentStorage, USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage].StorageDescription,
+                                                                                 USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage].VolumeLabel);
+            USBH_MTP_Info.is_ready = 1;
+            USBH_MTP_Info.state = USBH_MTP_IDLE;
+        }
+        break;
+
+    case USBH_MTP_IDLE:
+        if(abs((int)USBH->FRAMENR - (int)USBH_MTP_Info.events.timer) >= USBH_MTP_Info.events.poll)
+        {
+            USBH_MTP_Info.events.timer = USBH->FRAMENR;
+
+            USBH_MTP_Info.state = USBH_MTP_EVENT;
+        }
+        else
+        {
+            status = USBH_OK;
+        }
+        break;
+
+    case USBH_MTP_EVENT_CHECK:
+        if(abs((int)USBH->FRAMENR - (int)USBH_MTP_Info.events.timer) >= USBH_MTP_Info.events.poll)
+        {
+            USBH_MTP_Info.events.timer = USBH->FRAMENR;
+
+            USBH_MTP_Info.state = USBH_MTP_EVENT;
+        }
+        else
+        {
+            USBH_MTP_Info.state = USBH_MTP_TRANSFER;    // Event 查询是在数据传输中间插入的,返回数据传输
+        }
+        break;
+
+    case USBH_MTP_EVENT:
+        if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.NotifyEp, USBH_MTP_Info.NotifyEpDATAX, USBH_MTP_Info.NotifyEpSize))
+        {
+            USBH_MTP_Info.state = USBH_MTP_EVENT_WAIT;
+        }
+        break;
+
+    case USBH_MTP_EVENT_WAIT:
+        resp = USBH_State();
+        if(resp == USBR_ACK)
+        {
+            USBH_MTP_Info.NotifyEpDATAX ^= 1;
+
+            USBH_ReadRxBuffer((uint8_t *)&USBH_MTP_Info.events.container, USBH_MTP_Info.NotifyEpSize);
+
+            USBH_MTP_EventsCallback(phost, USBH_MTP_Info.events.container.code, USBH_MTP_Info.events.container.param1);
+        }
+
+        if((USBH_MTP_Info.XferState == USBH_MTP_XFER_DATA_OUT) ||
+           (USBH_MTP_Info.XferState == USBH_MTP_XFER_DATA_IN))
+        {
+            USBH_MTP_Info.state = USBH_MTP_TRANSFER;    // Event 查询是在数据传输中间插入的,返回数据传输
+        }
+        else
+        {
+            USBH_MTP_Info.state = USBH_MTP_IDLE;
+        }
+        break;
+
+    case USBH_MTP_TRANSFER:
+        USBH_MTP_XferProcess(phost);
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_XferProcess()
+* 功能说明:
+* 输    入: USBH_Info_t *phost
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void USBH_MTP_XferProcess(USBH_Info_t *phost)
+{
+    USBH_Resp resp;
+    uint32_t size;
+
+    USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+    switch(USBH_MTP_Info.XferState)
+    {
+    case USBH_MTP_XFER_OP_REQ:
+        if(USBH_SendOutPacket(phost->Device.Address, USBH_MTP_Info.OutEp, USBH_MTP_Info.OutEpDATAX, (uint8_t *)&USBH_MTP_Info.op_container, USBH_MTP_Info.op_container.length))
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ_WAIT;
+        }
+        break;
+
+    case USBH_MTP_XFER_OP_REQ_WAIT:
+        resp = USBH_State();
+        if(resp == USBR_ACK)
+        {
+            USBH_MTP_Info.OutEpDATAX ^= 1;
+
+            if(USBH_MTP_Info.flags == PTP_DP_NODATA)
+            {
+                USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
+            }
+            else if(USBH_MTP_Info.flags == PTP_DP_SENDDATA)
+            {
+                USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT;
+            }
+            else if(USBH_MTP_Info.flags == PTP_DP_GETDATA)
+            {
+                USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
+            }
+        }
+        else if(resp == USBR_NAK)
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;     // Resend Request
+        }
+        else if(resp == USBR_STALL)
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
+        }
+        break;
+
+    case USBH_MTP_XFER_DATA_OUT:
+        size = USBH_MTP_Info.data_len > USBH_MTP_Info.OutEpSize ? USBH_MTP_Info.OutEpSize : USBH_MTP_Info.data_len;
+        if(USBH_SendOutPacket(phost->Device.Address, USBH_MTP_Info.OutEp, USBH_MTP_Info.OutEpDATAX, USBH_MTP_Info.data_ptr, size))
+        {
+            USBH_MTP_Info.XferState  = USBH_MTP_XFER_DATA_OUT_WAIT;
+        }
+        break;
+
+    case USBH_MTP_XFER_DATA_OUT_WAIT:
+        resp = USBH_State();
+        if(resp == USBR_ACK)
+        {
+            USBH_MTP_Info.OutEpDATAX ^= 1;
+
+            if(USBH_MTP_Info.data_len > USBH_MTP_Info.OutEpSize)
+            {
+                USBH_MTP_Info.data_ptr += USBH_MTP_Info.OutEpSize;
+                USBH_MTP_Info.data_len -= USBH_MTP_Info.OutEpSize;
+            }
+            else
+            {
+                USBH_MTP_Info.data_len = 0;
+            }
+
+            if(USBH_MTP_Info.data_len > 0)
+            {
+                USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT;
+            }
+            else
+            {
+                USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
+            }
+        }
+        else if(resp == USBR_NAK)
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT;       // Resend same data
+
+            USBH_MTP_Info.state = USBH_MTP_EVENT_CHECK;     // 从机返回 NAK 时,主机查询一下是否需要执行 Event 查询
+        }
+        else if(resp == USBR_STALL)
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
+        }
+        break;
+
+    case USBH_MTP_XFER_DATA_IN:
+        if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.InEp, USBH_MTP_Info.InEpDATAX, USBH_MTP_Info.InEpSize))
+        {
+            USBH_MTP_Info.XferState  = USBH_MTP_XFER_DATA_IN_WAIT;
+        }
+        break;
+
+    case USBH_MTP_XFER_DATA_IN_WAIT:
+        resp = USBH_State();
+        if(resp == USBR_ACK)
+        {
+            USBH_MTP_Info.InEpDATAX ^= 1;
+
+            uint32_t len = USBH_ReadRxBuffer(USBH_MTP_Info.data_ptr, USBH_MTP_Info.InEpSize);
+
+            if(USBH_MTP_Info.first_packet)
+            {
+                USBH_MTP_Info.data_len = *(uint32_t *)(void *)USBH_MTP_Info.data_ptr;
+
+                if(USBH_MTP_Info.first_packet == 3)
+                {
+                    len -= PTP_USB_BULK_HDR_LEN;
+                    USBH_MTP_Info.data_len -= PTP_USB_BULK_HDR_LEN;
+                    memcpy(USBH_MTP_Info.data_ptr, USBH_MTP_Info.data_ptr + PTP_USB_BULK_HDR_LEN, len);
+                }
+
+                USBH_MTP_Info.first_packet = 0;
+            }
+
+            USBH_MTP_Info.data_ptr += len;
+            USBH_MTP_Info.data_len -= len;
+
+            if((USBH_MTP_Info.data_len > 0) || (len == USBH_MTP_Info.InEpSize))
+            {
+                USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
+            }
+            else
+            {
+                USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
+            }
+        }
+        else if(resp == USBR_NAK)
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
+
+            USBH_MTP_Info.state = USBH_MTP_EVENT_CHECK;     // 从机返回 NAK 时,主机查询一下是否需要执行 Event 查询
+        }
+        else if(resp == USBR_STALL)
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
+        }
+        break;
+
+    case USBH_MTP_XFER_RESP:
+        if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.InEp, USBH_MTP_Info.InEpDATAX, USBH_MTP_Info.InEpSize))
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP_WAIT;
+        }
+        break;
+
+    case USBH_MTP_XFER_RESP_WAIT:
+        resp = USBH_State();
+        if(resp == USBR_ACK)
+        {
+            USBH_MTP_Info.InEpDATAX ^= 1;
+
+            USBH_ReadRxBuffer((uint8_t *)&USBH_MTP_Info.resp_container, USBH_MTP_Info.InEpSize);
+
+            if(USBH_MTP_Info.resp_container.code == PTP_RC_OK)
+            {
+                USBH_MTP_Info.XferStatus = USBH_OK;
+            }
+            else
+            {
+                USBH_MTP_Info.XferStatus = USBH_FAIL;
+            }
+            USBH_MTP_Info.state = USBH_MTP_Info.stateBkp;
+        }
+        else if(resp == USBR_NAK)
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
+        }
+        else if(resp == USBR_STALL)
+        {
+            USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
+        }
+        break;
+
+    case USBH_MTP_XFER_ERROR:
+        USBH_MTP_Info.XferStatus = USBH_FAIL;
+        USBH_MTP_Info.state = USBH_MTP_Info.stateBkp;
+        break;
+
+    default:
+        break;
+    }
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetDeviceInfo()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetDeviceInfo(USBH_Info_t *phost, PTP_DeviceInfo_t *dev_info)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetDeviceInfo;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            PTP_DecodeDeviceInfo(phost, dev_info);
+        }
+        break;
+
+    default:
+        break;
+    }
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_OpenSession()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_OpenSession(USBH_Info_t *phost, uint32_t session)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Init session params */
+        USBH_MTP_Info.transaction_id = 0x00000000U;
+        USBH_MTP_Info.session_id = session;
+        USBH_MTP_Info.flags = PTP_DP_NODATA;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_OpenSession;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = session;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetStorageIds()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetStorageIds(USBH_Info_t *phost, PTP_StorageIDs_t *storage_ids)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetStorageIDs;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            storage_ids->n = PTP_GetArray32(storage_ids->Storage, USBH_MTP_Info.data_container.payload, 0U);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetStorageInfo()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetStorageInfo(USBH_Info_t *phost, uint32_t storage_id, PTP_StorageInfo_t *storage_info)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetStorageInfo;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = storage_id;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            PTP_DecodeStorageInfo(phost, storage_info);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetNumObjects()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetNumObjects(USBH_Info_t *phost, uint32_t storage_id, uint32_t format, uint32_t folder, uint32_t *numobs)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_NODATA;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetNumObjects;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = storage_id;
+        USBH_MTP_Info.op_container.param2 = format;
+        USBH_MTP_Info.op_container.param3 = folder;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            *numobs = USBH_MTP_Info.resp_container.param1;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetObjectHandles()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetObjectHandles(USBH_Info_t *phost, uint32_t storage_id, uint32_t format, uint32_t folder, PTP_ObjectHandles_t *handles)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetObjectHandles;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = storage_id;
+        USBH_MTP_Info.op_container.param2 = format;
+        USBH_MTP_Info.op_container.param3 = folder;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            handles->n = PTP_GetArray32(handles->Handler, USBH_MTP_Info.data_container.payload, 0U);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetObjectInfo()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetObjectInfo(USBH_Info_t *phost, uint32_t handle, PTP_ObjectInfo_t *object_info)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetObjectInfo;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = handle;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            PTP_DecodeObjectInfo(phost, object_info);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetObject()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetObject(USBH_Info_t *phost, uint32_t handle, uint8_t *object)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = object;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 3;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetObject;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = handle;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetPartialObject()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetPartialObject(USBH_Info_t *phost, uint32_t handle, uint32_t offset, uint32_t maxbytes, uint8_t *object, uint32_t *len)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = object;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 3;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetPartialObject;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = handle;
+        USBH_MTP_Info.op_container.param2 = offset;
+        USBH_MTP_Info.op_container.param3 = maxbytes;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            *len = USBH_MTP_Info.resp_container.param1;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_DeleteObject()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_DeleteObject(USBH_Info_t *phost, uint32_t handle, uint32_t format)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_NODATA;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_DeleteObject;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = handle;
+        USBH_MTP_Info.op_container.param2 = format;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 2;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_SendObject()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_SendObject(USBH_Info_t *phost, uint32_t handle, uint8_t *object, uint32_t size)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_SENDDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = size + PTP_USB_BULK_HDR_LEN;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_SendObject;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
+
+        /* Fill data_container */
+        USBH_MTP_Info.data_container.length = USBH_MTP_Info.data_len;
+        USBH_MTP_Info.data_container.type = PTP_USB_CONTAINER_DATA;
+        USBH_MTP_Info.data_container.code = USBH_MTP_Info.op_container.code;
+        USBH_MTP_Info.data_container.trans_id = USBH_MTP_Info.op_container.trans_id;
+        memcpy(USBH_MTP_Info.data_container.payload, object, size);
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetDevicePropDesc()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetDevicePropDesc(USBH_Info_t *phost, uint16_t propcode, PTP_DevicePropDesc_t *devicepropertydesc)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetDevicePropDesc;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = propcode;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            uint8_t *data = USBH_MTP_Info.data_container.payload;
+
+            devicepropertydesc->DevicePropertyCode = PTP_LE16(&data[PTP_dpd_DevicePropertyCode]);
+            devicepropertydesc->DataType = PTP_LE16(&data[PTP_dpd_DataType]);
+            devicepropertydesc->GetSet = *(uint8_t *)(&data[PTP_dpd_GetSet]);
+            devicepropertydesc->FormFlag = PTP_DPFF_None;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetObjectPropsSupported()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetObjectPropsSupported(USBH_Info_t *phost, uint16_t ofc, uint32_t *propnum, uint16_t *props)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetObjectPropsSupported;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = ofc;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            *propnum = PTP_GetArray16(props, USBH_MTP_Info.data_container.payload, 0U);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetObjectPropDesc()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetObjectPropDesc(USBH_Info_t *phost, uint16_t opc, uint16_t ofc, PTP_ObjectPropDesc_t *opd)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetObjectPropDesc;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = opc;
+        USBH_MTP_Info.op_container.param2 = ofc;
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 2;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            PTP_DecodeObjectPropDesc(phost, opd, USBH_MTP_Info.data_len);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_GetObjectPropList()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+USBH_Status USBH_MTP_GetObjectPropList(USBH_Info_t *phost, uint32_t handle, MTP_Properties_t *pprops, uint32_t *nrofprops)
+{
+    USBH_Status status = USBH_BUSY;
+
+    switch(USBH_MTP_Info.OpState)
+    {
+    case USBH_MTP_OP_SEND:
+        /* Set operation request type */
+        USBH_MTP_Info.flags = PTP_DP_GETDATA;
+        USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
+        USBH_MTP_Info.data_len = 0;
+        USBH_MTP_Info.first_packet = 1;
+
+        /* Fill operation request params */
+        USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
+        USBH_MTP_Info.op_container.code = PTP_OC_GetObjPropList;
+        USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
+        USBH_MTP_Info.op_container.param1 = handle;
+        USBH_MTP_Info.op_container.param2 = 0x00000000U;  /* 0x00000000U should be "all formats" */
+        USBH_MTP_Info.op_container.param3 = 0xFFFFFFFFU;  /* 0xFFFFFFFFU should be "all properties" */
+        USBH_MTP_Info.op_container.param4 = 0x00000000U;
+        USBH_MTP_Info.op_container.param5 = 0xFFFFFFFFU;  /* Return full tree below the Param1 handle */
+        USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 5;
+
+        /* Setup State machine and start transfer */
+        USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
+        USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
+
+        USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
+        break;
+
+    case USBH_MTP_OP_WAIT:
+        if(USBH_MTP_Info.XferStatus != USBH_BUSY)
+        {
+            status = USBH_MTP_Info.XferStatus;
+            USBH_MTP_Info.XferStatus = USBH_BUSY;
+
+            USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
+        }
+        if(status == USBH_OK)
+        {
+            PTP_DecodeObjectPropList(phost, pprops, USBH_MTP_Info.data_len);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: USBH_MTP_EventsCallback()
+* 功能说明: The function informs that host has received an event
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+__attribute__((weak)) void USBH_MTP_EventsCallback(USBH_Info_t *phost, uint32_t event, uint32_t param)
+{
+}

+ 153 - 0
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.h

@@ -0,0 +1,153 @@
+#ifndef __USBH_MTP_H__
+#define __USBH_MTP_H__
+
+#include "usbh_mtp_ptp.h"
+
+
+typedef enum {
+    USBH_MTP_IDLE = 0,
+    USBH_MTP_GETDEVICEINFO,
+    USBH_MTP_OPENSESSION,
+    USBH_MTP_GETSTORAGEIDS,
+    USBH_MTP_GETSTORAGEINFO,
+    USBH_MTP_TRANSFER,
+    USBH_MTP_EVENT,
+    USBH_MTP_EVENT_WAIT,
+
+    /* Events may be interleaved within a data stream during a transaction.
+       It may be assumed that the Operation Request Phase and Response Phase are atomic, but the Data Phase
+       must allow for events to be communicated in either direction without interrupting data transfer.
+    */
+    USBH_MTP_EVENT_CHECK,
+} USBH_MTP_State;
+
+typedef enum {
+    USBH_MTP_OP_IDLE = 0,
+    USBH_MTP_OP_SEND,
+    USBH_MTP_OP_WAIT,
+    USBH_MTP_OP_ERROR,
+} USBH_MTP_OpState;
+
+typedef enum {
+    USBH_MTP_XFER_IDLE = 0,
+    USBH_MTP_XFER_OP_REQ,
+    USBH_MTP_XFER_OP_REQ_WAIT,
+    USBH_MTP_XFER_DATA_OUT,
+    USBH_MTP_XFER_DATA_OUT_WAIT,
+    USBH_MTP_XFER_DATA_IN,
+    USBH_MTP_XFER_DATA_IN_WAIT,
+    USBH_MTP_XFER_RESP,
+    USBH_MTP_XFER_RESP_WAIT,
+    USBH_MTP_XFER_ERROR,
+} USBH_MTP_XferState;
+
+
+typedef struct {
+    uint32_t timer;
+    uint16_t poll;
+    PTP_EventContainer_t container;
+} MTP_EventHandle_t;
+
+
+typedef struct {
+    uint8_t  InEp;
+    uint8_t  OutEp;
+    uint8_t  NotifyEp;
+    uint16_t InEpSize;
+    uint16_t OutEpSize;
+    uint16_t NotifyEpSize;
+    uint8_t  InEpDATAX;
+    uint8_t  OutEpDATAX;
+    uint8_t  NotifyEpDATAX;
+
+    USBH_MTP_State      state;
+    USBH_MTP_State      stateReq;
+    USBH_MTP_State      stateBkp;
+
+    USBH_MTP_OpState    OpState;
+    USBH_MTP_XferState  XferState;
+
+    USBH_Status         XferStatus;
+
+    PTP_OpContainer_t   op_container;
+    PTP_DataContainer_t data_container;
+    PTP_RespContainer_t resp_container;
+
+    uint32_t  session_id;
+    uint32_t  transaction_id;
+
+    uint32_t  flags;
+
+    uint8_t  *data_ptr;
+    uint32_t  data_len;
+    uint8_t   first_packet;     // 1 数据第一帧   3 数据第一帧,且需丢弃 header 不存储
+
+    PTP_DeviceInfo_t    devinfo;
+    PTP_StorageIDs_t    storids;
+    PTP_StorageInfo_t   storinfo[PTP_MAX_STORAGE_UNITS_NBR];
+
+    MTP_EventHandle_t   events;
+
+    uint32_t CurrentStorage;
+    uint32_t is_ready;
+} USBH_MTP_Info_t;
+
+extern USBH_MTP_Info_t USBH_MTP_Info;
+
+
+static uint32_t USBH_MTP_Ready(void)
+{
+    return USBH_MTP_Info.is_ready;
+}
+
+static uint32_t USBH_MTP_StorageCount(void)
+{
+    return USBH_MTP_Info.storids.n;
+}
+
+static uint32_t USBH_MTP_Storage(uint32_t index)
+{
+    return USBH_MTP_Info.storids.Storage[index];
+}
+
+
+USBH_Status USBH_MTP_GetDeviceInfo(USBH_Info_t *phost, PTP_DeviceInfo_t *dev_info);
+
+USBH_Status USBH_MTP_OpenSession(USBH_Info_t *phost, uint32_t session);
+
+USBH_Status USBH_MTP_GetStorageIds(USBH_Info_t *phost, PTP_StorageIDs_t *storage_ids);
+USBH_Status USBH_MTP_GetStorageInfo(USBH_Info_t *phost, uint32_t storage_id, PTP_StorageInfo_t *storage_info);
+
+USBH_Status USBH_MTP_GetNumObjects(USBH_Info_t *phost, uint32_t storage_id, uint32_t format, uint32_t folder, uint32_t *numobs);
+USBH_Status USBH_MTP_GetObjectHandles(USBH_Info_t *phost, uint32_t storage_id, uint32_t format, uint32_t folder, PTP_ObjectHandles_t *handles);
+
+USBH_Status USBH_MTP_GetObjectInfo(USBH_Info_t *phost, uint32_t handle, PTP_ObjectInfo_t *object_info);
+
+USBH_Status USBH_MTP_GetObject(USBH_Info_t *phost, uint32_t handle, uint8_t *object);
+USBH_Status USBH_MTP_GetPartialObject(USBH_Info_t *phost, uint32_t handle, uint32_t offset, uint32_t maxbytes, uint8_t *object, uint32_t *len);
+
+USBH_Status USBH_MTP_DeleteObject(USBH_Info_t *phost, uint32_t handle, uint32_t format);
+USBH_Status USBH_MTP_SendObject(USBH_Info_t *phost, uint32_t handle, uint8_t *object, uint32_t size);
+
+USBH_Status USBH_MTP_GetDevicePropDesc(USBH_Info_t *phost, uint16_t propcode, PTP_DevicePropDesc_t *devicepropertydesc);
+
+USBH_Status USBH_MTP_GetObjectPropsSupported(USBH_Info_t *phost, uint16_t ofc, uint32_t *propnum, uint16_t *props);
+USBH_Status USBH_MTP_GetObjectPropDesc(USBH_Info_t *phost, uint16_t opc, uint16_t ofc, PTP_ObjectPropDesc_t *opd);
+USBH_Status USBH_MTP_GetObjectPropList(USBH_Info_t *phost, uint32_t handle, MTP_Properties_t *pprops, uint32_t *nrofprops);
+
+
+void USBH_MTP_EventsCallback(USBH_Info_t *phost, uint32_t event, uint32_t param);
+
+
+#define USBH_TObreak(ms)                            \
+    {                                               \
+        static int start;                           \
+        start = USBH->FRAMENR;                      \
+        if(abs((int)USBH->FRAMENR - start) > ms)    \
+        {                                           \
+            break;                                  \
+        }                                           \
+    }
+
+
+#endif // __USBH_MTP_H__

+ 376 - 0
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.c

@@ -0,0 +1,376 @@
+/******************************************************************************************************************************************
+* 文件名称: usbh_mtp.c
+* 功能说明: This file includes the PTP operations layer.
+* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
+* 注意事项:
+* 版本日期: V1.1.0      2020年11月3日
+* 升级记录:
+*
+*
+*******************************************************************************************************************************************
+* @attention
+*
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
+* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
+* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
+* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
+* -ECTION WITH THEIR PRODUCTS.
+*
+* COPYRIGHT 2012 Synwit Technology
+*******************************************************************************************************************************************/
+#include <string.h>
+#include "SWM341.h"
+#include "usbh_core.h"
+#include "usbh_mtp.h"
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_GetDevicePropValue()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void PTP_GetDevicePropValue(USBH_Info_t *phost, uint32_t *offset, uint32_t total, PTP_PropertyValue_t *value, uint16_t datatype)
+{
+    uint8_t *data = USBH_MTP_Info.data_container.payload;
+    uint16_t len;
+    switch(datatype)
+    {
+    case PTP_DTC_INT8:
+        value->i8 = *(int8_t *)(void *) & (data[*offset]);
+        *offset += 1U;
+        break;
+
+    case PTP_DTC_UINT8:
+        value->u8 = *(uint8_t *) & (data[*offset]);
+        *offset += 1U;
+        break;
+
+    case PTP_DTC_INT16:
+        value->i16 = *(int16_t *)(void *) & (data[*offset]);
+        *offset += 2U;
+        break;
+
+    case PTP_DTC_UINT16:
+        value->u16 = PTP_LE16(&(data[*offset]));
+        *offset += 2U;
+        break;
+
+    case PTP_DTC_INT32:
+        value->i32 = *(int32_t *)(void *)(&(data[*offset]));
+        *offset += 4U;
+        break;
+
+    case PTP_DTC_UINT32:
+        value->u32 = PTP_LE32(&(data[*offset]));
+        *offset += 4U;
+        break;
+
+    case PTP_DTC_INT64:
+        value->i64 = *(int64_t *)(void *)(&(data[*offset]));
+        *offset += 8U;
+        break;
+
+    case PTP_DTC_UINT64:
+        value->u64 = PTP_LE64(&(data[*offset]));
+        *offset += 8U;
+        break;
+
+    case PTP_DTC_UINT128:
+        *offset += 16U;
+        break;
+
+    case PTP_DTC_INT128:
+        *offset += 16U;
+        break;
+
+    case PTP_DTC_STR:
+        PTP_GetString((uint8_t *)(void *)value->str, (uint8_t *) & (data[*offset]), &len);
+        *offset += (uint32_t)(len * 2U) + 1U;
+        break;
+
+    default:
+        break;
+    }
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_GetString()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void PTP_GetString(uint8_t *str, uint8_t *data, uint16_t *len)
+{
+    uint16_t strlength;
+    uint16_t idx;
+
+    *len = data[0];
+    strlength = (uint16_t)(2U * (uint32_t)data[0]);
+    data ++; /* Adjust the offset ignoring the String Len */
+
+    for (idx = 0U; idx < strlength; idx += 2U)
+    {
+        /* Copy Only the string and ignore the UNICODE ID, hence add the src */
+        *str = data[idx];
+        str++;
+    }
+    *str = 0U; /* mark end of string */
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_GetArray16()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t PTP_GetArray16(uint16_t *array, uint8_t *data, uint32_t offset)
+{
+    uint32_t size, idx = 0U;
+
+    size = PTP_LE32(&data[offset]);
+    while(size > idx)
+    {
+        array[idx] = (uint16_t)data[offset + (sizeof(uint16_t) * (idx + 2U))];
+        idx++;
+    }
+    return size;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_GetArray32()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t PTP_GetArray32(uint32_t *array, uint8_t *data, uint32_t offset)
+{
+    uint32_t size, idx = 0U;
+
+    size = PTP_LE32(&data[offset]);
+    while(size > idx)
+    {
+        array[idx] = PTP_LE32(&data[offset + (sizeof(uint32_t) * (idx + 1U))]);
+        idx++;
+    }
+    return size;
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_DecodeDeviceInfo()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void PTP_DecodeDeviceInfo(USBH_Info_t *phost, PTP_DeviceInfo_t *dev_info)
+{
+    uint8_t *data = USBH_MTP_Info.data_container.payload;
+    uint32_t totallen;
+    uint16_t len;
+
+    dev_info->StandardVersion = PTP_LE16(&data[PTP_di_StandardVersion]);
+    dev_info->VendorExtensionID = PTP_LE32(&data[PTP_di_VendorExtensionID]);
+    dev_info->VendorExtensionVersion = PTP_LE16(&data[PTP_di_VendorExtensionVersion]);
+    PTP_GetString(dev_info->VendorExtensionDesc, &data[PTP_di_VendorExtensionDesc], &len);
+
+    totallen = (uint32_t)(len * 2U) + 1U;
+    dev_info->FunctionalMode = PTP_LE16(&data[PTP_di_FunctionalMode + totallen]);
+    dev_info->OperationsSupportedNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->OperationsSupported, data, PTP_di_OperationsSupported + totallen);
+
+    totallen = totallen + (dev_info->OperationsSupportedNbr * sizeof(uint16_t)) + sizeof(uint32_t);
+    dev_info->EventsSupportedNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->EventsSupported, data, PTP_di_OperationsSupported + totallen);
+
+    totallen = totallen + (dev_info->EventsSupportedNbr * sizeof(uint16_t)) + sizeof(uint32_t);
+    dev_info->DevicePropertiesSupportedNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->DevicePropertiesSupported, data, PTP_di_OperationsSupported + totallen);
+
+    totallen = totallen + (dev_info->DevicePropertiesSupportedNbr * sizeof(uint16_t)) + sizeof(uint32_t);
+
+    dev_info->CaptureFormatsNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->CaptureFormats, data, PTP_di_OperationsSupported + totallen);
+
+    totallen = totallen + (dev_info->CaptureFormatsNbr * sizeof(uint16_t)) + sizeof(uint32_t);
+    dev_info->ImageFormatsNbr =  PTP_GetArray16((uint16_t *)(void *)&dev_info->ImageFormats, data, PTP_di_OperationsSupported + totallen);
+
+    totallen = totallen + (dev_info->ImageFormatsNbr * sizeof(uint16_t)) + sizeof(uint32_t);
+    PTP_GetString(dev_info->Manufacturer, &data[PTP_di_OperationsSupported + totallen], &len);
+
+    totallen += (uint32_t)(len * 2U) + 1U;
+    PTP_GetString(dev_info->Model, &data[PTP_di_OperationsSupported + totallen], &len);
+
+    totallen += (uint32_t)(len * 2U) + 1U;
+    PTP_GetString(dev_info->DeviceVersion, &data[PTP_di_OperationsSupported + totallen], &len);
+
+    totallen += (uint32_t)(len * 2U) + 1U;
+    PTP_GetString(dev_info->SerialNumber, &data[PTP_di_OperationsSupported + totallen], &len);
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_DecodeStorageInfo()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void PTP_DecodeStorageInfo(USBH_Info_t *phost, PTP_StorageInfo_t *storage_info)
+{
+    uint8_t *data = USBH_MTP_Info.data_container.payload;
+    uint16_t len;
+
+    storage_info->StorageType = PTP_LE16(&data[PTP_si_StorageType]);
+    storage_info->FilesystemType = PTP_LE16(&data[PTP_si_FilesystemType]);
+    storage_info->AccessCapability = PTP_LE16(&data[PTP_si_AccessCapability]);
+    storage_info->MaxCapability = PTP_LE64(&data[PTP_si_MaxCapability]);
+    storage_info->FreeSpaceInBytes = PTP_LE64(&data[PTP_si_FreeSpaceInBytes]);
+    storage_info->FreeSpaceInImages = PTP_LE32(&data[PTP_si_FreeSpaceInImages]);
+
+    PTP_GetString(storage_info->StorageDescription, &data[PTP_si_StorageDescription], &len);
+    PTP_GetString(storage_info->VolumeLabel, &data[PTP_si_StorageDescription + (len * 2U) + 1U], &len);
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_DecodeObjectInfo()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void PTP_DecodeObjectInfo(USBH_Info_t *phost, PTP_ObjectInfo_t *object_info)
+{
+    uint8_t *data = USBH_MTP_Info.data_container.payload;
+    uint16_t filenamelen;
+
+    object_info->StorageID = PTP_LE32(&data[PTP_oi_StorageID]);
+    object_info->ObjectFormat = PTP_LE16(&data[PTP_oi_ObjectFormat]);
+    object_info->ProtectionStatus = PTP_LE16(&data[PTP_oi_ProtectionStatus]);
+    object_info->ObjectCompressedSize = PTP_LE64(&data[PTP_oi_ObjectCompressedSize]);
+
+    /* For Samsung Galaxy */
+    if((data[PTP_oi_filenamelen] == 0U) && (data[PTP_oi_filenamelen + 4U] != 0U))
+    {
+        data += 4;
+    }
+    object_info->ThumbFormat = PTP_LE16(&data[PTP_oi_ThumbFormat]);
+    object_info->ThumbCompressedSize = PTP_LE32(&data[PTP_oi_ThumbCompressedSize]);
+    object_info->ThumbPixWidth = PTP_LE32(&data[PTP_oi_ThumbPixWidth]);
+    object_info->ThumbPixHeight = PTP_LE32(&data[PTP_oi_ThumbPixHeight]);
+    object_info->ImagePixWidth = PTP_LE32(&data[PTP_oi_ImagePixWidth]);
+    object_info->ImagePixHeight = PTP_LE32(&data[PTP_oi_ImagePixHeight]);
+    object_info->ImageBitDepth = PTP_LE32(&data[PTP_oi_ImageBitDepth]);
+    object_info->ParentObject = PTP_LE32(&data[PTP_oi_ParentObject]);
+    object_info->AssociationType = PTP_LE16(&data[PTP_oi_AssociationType]);
+    object_info->AssociationDesc = PTP_LE32(&data[PTP_oi_AssociationDesc]);
+    object_info->SequenceNumber = PTP_LE32(&data[PTP_oi_SequenceNumber]);
+    PTP_GetString(object_info->Filename, &data[PTP_oi_filenamelen], &filenamelen);
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_DecodeObjectPropDesc()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+void PTP_DecodeObjectPropDesc(USBH_Info_t *phost, PTP_ObjectPropDesc_t *opd, uint32_t opdlen)
+{
+    uint8_t *data = USBH_MTP_Info.data_container.payload;
+    uint32_t offset = 0U, i;
+
+    opd->ObjectPropertyCode = PTP_LE16(&data[PTP_opd_ObjectPropertyCode]);
+    opd->DataType = PTP_LE16(&data[PTP_opd_DataType]);
+    opd->GetSet = *(uint8_t *)(&data[PTP_opd_GetSet]);
+
+    offset = PTP_opd_FactoryDefaultValue;
+    PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType);
+
+    opd->GroupCode = PTP_LE32(&data[offset]);
+    offset += sizeof(uint32_t);
+
+    opd->FormFlag = *(uint8_t *)(&data[offset]);
+    offset += sizeof(uint8_t);
+
+    switch(opd->FormFlag)
+    {
+    case PTP_OPFF_Range:
+        PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType);
+        PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType);
+        PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType);
+        break;
+
+    case PTP_OPFF_Enumeration:
+        opd->FORM.Enum.NumberOfValues = PTP_LE16(&data[offset]);
+        offset += sizeof(uint16_t);
+
+        for(i = 0U; i < opd->FORM.Enum.NumberOfValues ; i++)
+        {
+            PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType);
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+
+/******************************************************************************************************************************************
+* 函数名称: PTP_DecodeObjectPropList()
+* 功能说明:
+* 输    入: 无
+* 输    出: 无
+* 注意事项: 无
+******************************************************************************************************************************************/
+uint32_t PTP_DecodeObjectPropList(USBH_Info_t *phost, MTP_Properties_t *props, uint32_t len)
+{
+    uint8_t *data = USBH_MTP_Info.data_container.payload;
+    uint32_t prop_count;
+    uint32_t offset = 0U, i;
+
+    prop_count = PTP_LE32(data);
+    if(prop_count == 0U)
+    {
+        return 0;
+    }
+
+    data += sizeof(uint32_t);
+    len -= sizeof(uint32_t);
+
+    for(i = 0U; i < prop_count; i++)
+    {
+        if(len <= 0U)
+        {
+            return 0;
+        }
+
+        props[i].ObjectHandle = PTP_LE32(data);
+        data += sizeof(uint32_t);
+        len -= sizeof(uint32_t);
+
+        props[i].property = PTP_LE16(data);
+        data += sizeof(uint16_t);
+        len -= sizeof(uint16_t);
+
+        props[i].datatype = PTP_LE16(data);
+        data += sizeof(uint16_t);
+        len -= sizeof(uint16_t);
+
+        offset = 0U;
+
+        PTP_GetDevicePropValue(phost, &offset, len, &props[i].propval, props[i].datatype);
+
+        data += offset;
+        len -= offset;
+    }
+
+    return prop_count;
+}

+ 758 - 0
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.h

@@ -0,0 +1,758 @@
+#ifndef __USBH_MTP_PTP_H__
+#define __USBH_MTP_PTP_H__
+
+#include <stdint.h>
+
+#define PTP_USB_BULK_HDR_LEN    ((2 * sizeof(uint32_t)) + (2 * sizeof(uint16_t)))
+
+typedef struct {
+    uint32_t length;
+    uint16_t type;
+    uint16_t code;
+    uint32_t trans_id;
+    uint32_t param1;
+    uint32_t param2;
+    uint32_t param3;
+    uint32_t param4;
+    uint32_t param5;
+} PTP_OpContainer_t;
+
+typedef struct {
+    uint32_t length;
+    uint16_t type;
+    uint16_t code;
+    uint32_t trans_id;
+    uint8_t payload[4096];
+} PTP_DataContainer_t;
+
+typedef struct {
+    uint32_t length;
+    uint16_t type;
+    uint16_t code;
+    uint32_t trans_id;
+    uint32_t param1;
+    uint32_t param2;
+    uint32_t param3;
+    uint32_t param4;
+    uint32_t param5;
+} PTP_RespContainer_t;
+
+/* PTP USB Asynchronous Event Interrupt Data Format */
+typedef struct {
+    uint32_t length;
+    uint16_t type;
+    uint16_t code;
+    uint32_t trans_id;
+    uint32_t param1;
+    uint32_t param2;
+    uint32_t param3;
+} PTP_EventContainer_t;
+
+
+/* Operation Codes */
+
+/* PTP v1.0 operation codes */
+#define PTP_OC_Undefined                    0x1000U
+#define PTP_OC_GetDeviceInfo                0x1001U
+#define PTP_OC_OpenSession                  0x1002U
+#define PTP_OC_CloseSession                 0x1003U
+#define PTP_OC_GetStorageIDs                0x1004U
+#define PTP_OC_GetStorageInfo               0x1005U
+#define PTP_OC_GetNumObjects                0x1006U
+#define PTP_OC_GetObjectHandles             0x1007U
+#define PTP_OC_GetObjectInfo                0x1008U
+#define PTP_OC_GetObject                    0x1009U
+#define PTP_OC_GetThumb                     0x100AU
+#define PTP_OC_DeleteObject                 0x100BU
+#define PTP_OC_SendObjectInfo               0x100CU
+#define PTP_OC_SendObject                   0x100DU
+#define PTP_OC_InitiateCapture              0x100EU
+#define PTP_OC_FormatStore                  0x100FU
+#define PTP_OC_ResetDevice                  0x1010U
+#define PTP_OC_SelfTest                     0x1011U
+#define PTP_OC_SetObjectProtection          0x1012U
+#define PTP_OC_PowerDown                    0x1013U
+#define PTP_OC_GetDevicePropDesc            0x1014U
+#define PTP_OC_GetDevicePropValue           0x1015U
+#define PTP_OC_SetDevicePropValue           0x1016U
+#define PTP_OC_ResetDevicePropValue         0x1017U
+#define PTP_OC_TerminateOpenCapture         0x1018U
+#define PTP_OC_MoveObject                   0x1019U
+#define PTP_OC_CopyObject                   0x101AU
+#define PTP_OC_GetPartialObject             0x101BU
+#define PTP_OC_InitiateOpenCapture          0x101CU
+
+/* PTP v1.1 operation codes */
+#define PTP_OC_StartEnumHandles             0x101DU
+#define PTP_OC_EnumHandles                  0x101EU
+#define PTP_OC_StopEnumHandles              0x101FU
+#define PTP_OC_GetVendorExtensionMaps       0x1020U
+#define PTP_OC_GetVendorDeviceInfo          0x1021U
+#define PTP_OC_GetResizedImageObject        0x1022U
+#define PTP_OC_GetFilesystemManifest        0x1023U
+#define PTP_OC_GetStreamInfo                0x1024U
+#define PTP_OC_GetStream                    0x1025U
+
+/* Microsoft / MTP extension codes */
+#define PTP_OC_GetObjectPropsSupported      0x9801U
+#define PTP_OC_GetObjectPropDesc            0x9802U
+#define PTP_OC_GetObjectPropValue           0x9803U
+#define PTP_OC_SetObjectPropValue           0x9804U
+#define PTP_OC_GetObjPropList               0x9805U
+#define PTP_OC_SetObjPropList               0x9806U
+#define PTP_OC_GetInterdependendPropdesc    0x9807U
+#define PTP_OC_SendObjectPropList           0x9808U
+#define PTP_OC_GetObjectReferences          0x9810U
+#define PTP_OC_SetObjectReferences          0x9811U
+#define PTP_OC_UpdateDeviceFirmware         0x9812U
+#define PTP_OC_Skip                         0x9820U
+
+
+/* Response Codes */
+
+/* PTP v1.0 response codes */
+#define PTP_RC_Undefined                    0x2000U
+#define PTP_RC_OK                           0x2001U
+#define PTP_RC_GeneralError                 0x2002U
+#define PTP_RC_SessionNotOpen               0x2003U
+#define PTP_RC_InvalidTransactionID         0x2004U
+#define PTP_RC_OperationNotSupported        0x2005U
+#define PTP_RC_ParameterNotSupported        0x2006U
+#define PTP_RC_IncompleteTransfer           0x2007U
+#define PTP_RC_InvalidStorageId             0x2008U
+#define PTP_RC_InvalidObjectHandle          0x2009U
+#define PTP_RC_DevicePropNotSupported       0x200AU
+#define PTP_RC_InvalidObjectFormatCode      0x200BU
+#define PTP_RC_StoreFull                    0x200CU
+#define PTP_RC_ObjectWriteProtected         0x200DU
+#define PTP_RC_StoreReadOnly                0x200EU
+#define PTP_RC_AccessDenied                 0x200FU
+#define PTP_RC_NoThumbnailPresent           0x2010U
+#define PTP_RC_SelfTestFailed               0x2011U
+#define PTP_RC_PartialDeletion              0x2012U
+#define PTP_RC_StoreNotAvailable            0x2013U
+#define PTP_RC_SpecByFormatUnsupported      0x2014U
+#define PTP_RC_NoValidObjectInfo            0x2015U
+#define PTP_RC_InvalidCodeFormat            0x2016U
+#define PTP_RC_UnknownVendorCode            0x2017U
+#define PTP_RC_CaptureAlreadyTerminated     0x2018U
+#define PTP_RC_DeviceBusy                   0x2019U
+#define PTP_RC_InvalidParentObject          0x201AU
+#define PTP_RC_InvalidDevicePropFormat      0x201BU
+#define PTP_RC_InvalidDevicePropValue       0x201CU
+#define PTP_RC_InvalidParameter             0x201DU
+#define PTP_RC_SessionAlreadyOpened         0x201EU
+#define PTP_RC_TransactionCanceled          0x201FU
+#define PTP_RC_SpecOfDestinationUnsupported 0x2020U
+
+/* PTP v1.1 response codes */
+#define PTP_RC_InvalidEnumHandle            0x2021U
+#define PTP_RC_NoStreamEnabled              0x2022U
+#define PTP_RC_InvalidDataSet               0x2023U
+
+
+/* USB container types */
+#define PTP_USB_CONTAINER_UNDEFINED         0x0000U
+#define PTP_USB_CONTAINER_COMMAND           0x0001U
+#define PTP_USB_CONTAINER_DATA              0x0002U
+#define PTP_USB_CONTAINER_RESPONSE          0x0003U
+#define PTP_USB_CONTAINER_EVENT             0x0004U
+
+
+/* Transaction data phase description */
+#define PTP_DP_NODATA                       0x0000U // no data phase
+#define PTP_DP_SENDDATA                     0x0001U // sending data
+#define PTP_DP_GETDATA                      0x0002U // receiving data
+#define PTP_DP_DATA_MASK                    0x00ffU // data phase mask
+
+
+/* DeviceInfo data offset */
+#define PTP_di_StandardVersion                            0U
+#define PTP_di_VendorExtensionID                          2U
+#define PTP_di_VendorExtensionVersion                     6U
+#define PTP_di_VendorExtensionDesc                        8U
+#define PTP_di_FunctionalMode                             8U
+#define PTP_di_OperationsSupported                        10U
+
+/* Max info items size */
+#define PTP_SUPPORTED_OPERATIONS_NBR                      100U
+#define PTP_SUPPORTED_EVENTS_NBR                          100U
+#define PTP_SUPPORTED_PROPRIETIES_NBR                     100U
+#define PTP_CAPTURE_FORMATS_NBR                           100U
+#define PTP_IMAGE_FORMATS_NBR                             100U
+#define PTP_MAX_STR_SIZE                                  255U
+
+/* PTP device info structure */
+typedef struct {
+    uint16_t StandardVersion;
+    uint32_t VendorExtensionID;
+    uint16_t VendorExtensionVersion;
+    uint8_t  VendorExtensionDesc[PTP_MAX_STR_SIZE];
+    uint16_t FunctionalMode;
+    uint32_t OperationsSupportedNbr;
+    uint16_t OperationsSupported[PTP_SUPPORTED_OPERATIONS_NBR];
+    uint32_t EventsSupportedNbr;
+    uint16_t EventsSupported[PTP_SUPPORTED_EVENTS_NBR];
+    uint32_t DevicePropertiesSupportedNbr;
+    uint16_t DevicePropertiesSupported[PTP_SUPPORTED_PROPRIETIES_NBR];
+    uint32_t CaptureFormatsNbr;
+    uint16_t CaptureFormats[PTP_CAPTURE_FORMATS_NBR];
+    uint32_t ImageFormatsNbr;
+    uint16_t ImageFormats[PTP_IMAGE_FORMATS_NBR];
+    uint8_t  Manufacturer[PTP_MAX_STR_SIZE];
+    uint8_t  Model[PTP_MAX_STR_SIZE];
+    uint8_t  DeviceVersion[PTP_MAX_STR_SIZE];
+    uint8_t  SerialNumber[PTP_MAX_STR_SIZE];
+} PTP_DeviceInfo_t;
+
+
+#define PTP_MAX_STORAGE_UNITS_NBR   3
+
+/* PTP storageIDs structute (returned by GetStorageIDs) */
+typedef struct {
+    uint32_t n;
+    uint32_t Storage[PTP_MAX_STORAGE_UNITS_NBR];
+} PTP_StorageIDs_t;
+
+
+/* PTP StorageInfo structure (returned by GetStorageInfo) */
+#define PTP_si_StorageType                                0U
+#define PTP_si_FilesystemType                             2U
+#define PTP_si_AccessCapability                           4U
+#define PTP_si_MaxCapability                              6U
+#define PTP_si_FreeSpaceInBytes                           14U
+#define PTP_si_FreeSpaceInImages                          22U
+#define PTP_si_StorageDescription                         26U
+
+/* PTP Storage Types */
+#define PTP_ST_Undefined                                  0x0000U
+#define PTP_ST_FixedROM                                   0x0001U
+#define PTP_ST_RemovableROM                               0x0002U
+#define PTP_ST_FixedRAM                                   0x0003U
+#define PTP_ST_RemovableRAM                               0x0004U
+
+/* PTP FilesystemType Values */
+#define PTP_FST_Undefined                                 0x0000U
+#define PTP_FST_GenericFlat                               0x0001U
+#define PTP_FST_GenericHierarchical                       0x0002U
+#define PTP_FST_DCF                                       0x0003U
+
+/* PTP StorageInfo AccessCapability Values */
+#define PTP_AC_ReadWrite                                  0x0000U
+#define PTP_AC_ReadOnly                                   0x0001U
+#define PTP_AC_ReadOnly_with_Object_Deletion              0x0002U
+
+typedef struct {
+    uint16_t StorageType;
+    uint16_t FilesystemType;
+    uint16_t AccessCapability;
+    uint64_t MaxCapability;
+    uint64_t FreeSpaceInBytes;
+    uint32_t FreeSpaceInImages;
+    uint8_t  StorageDescription[PTP_MAX_STR_SIZE];
+    uint8_t  VolumeLabel[PTP_MAX_STR_SIZE];
+} PTP_StorageInfo_t;
+
+
+/* PTP Object Format Codes */
+/* ancillary formats */
+#define PTP_OFC_Undefined                                 0x3000U
+#define PTP_OFC_Defined                                   0x3800U
+#define PTP_OFC_Association                               0x3001U
+#define PTP_OFC_Script                                    0x3002U
+#define PTP_OFC_Executable                                0x3003U
+#define PTP_OFC_Text                                      0x3004U
+#define PTP_OFC_HTML                                      0x3005U
+#define PTP_OFC_DPOF                                      0x3006U
+#define PTP_OFC_AIFF                                      0x3007U
+#define PTP_OFC_WAV                                       0x3008U
+#define PTP_OFC_MP3                                       0x3009U
+#define PTP_OFC_AVI                                       0x300AU
+#define PTP_OFC_MPEG                                      0x300BU
+#define PTP_OFC_ASF                                       0x300CU
+#define PTP_OFC_QT                                        0x300DU /* guessing */
+/* image formats */
+#define PTP_OFC_EXIF_JPEG                                 0x3801U
+#define PTP_OFC_TIFF_EP                                   0x3802U
+#define PTP_OFC_FlashPix                                  0x3803U
+#define PTP_OFC_BMP                                       0x3804U
+#define PTP_OFC_CIFF                                      0x3805U
+#define PTP_OFC_Undefined_0x3806                          0x3806U
+#define PTP_OFC_GIF                                       0x3807U
+#define PTP_OFC_JFIF                                      0x3808U
+#define PTP_OFC_PCD                                       0x3809U
+#define PTP_OFC_PICT                                      0x380AU
+#define PTP_OFC_PNG                                       0x380BU
+#define PTP_OFC_Undefined_0x380C                          0x380CU
+#define PTP_OFC_TIFF                                      0x380DU
+#define PTP_OFC_TIFF_IT                                   0x380EU
+#define PTP_OFC_JP2                                       0x380FU
+#define PTP_OFC_JPX                                       0x3810U
+/* ptp v1.1 has only DNG new */
+#define PTP_OFC_DNG                                       0x3811U
+
+/* MTP extensions */
+#define PTP_OFC_MTP_MediaCard                             0xb211U
+#define PTP_OFC_MTP_MediaCardGroup                        0xb212U
+#define PTP_OFC_MTP_Encounter                             0xb213U
+#define PTP_OFC_MTP_EncounterBox                          0xb214U
+#define PTP_OFC_MTP_M4A                                   0xb215U
+#define PTP_OFC_MTP_ZUNEUNDEFINED                         0xb217U/* Unknown file type */
+#define PTP_OFC_MTP_Firmware                              0xb802U
+#define PTP_OFC_MTP_WindowsImageFormat                    0xb881U
+#define PTP_OFC_MTP_UndefinedAudio                        0xb900U
+#define PTP_OFC_MTP_WMA                                   0xb901U
+#define PTP_OFC_MTP_OGG                                   0xb902U
+#define PTP_OFC_MTP_AAC                                   0xb903U
+#define PTP_OFC_MTP_AudibleCod                            0xb904U
+#define PTP_OFC_MTP_FLAC                                  0xb906U
+#define PTP_OFC_MTP_SamsungPlaylist                       0xb909U
+#define PTP_OFC_MTP_UndefinedVideo                        0xb980U
+#define PTP_OFC_MTP_WMV                                   0xb981U
+#define PTP_OFC_MTP_MP4                                   0xb982U
+#define PTP_OFC_MTP_MP2                                   0xb983U
+#define PTP_OFC_MTP_3GP                                   0xb984U
+#define PTP_OFC_MTP_UndefinedCollection                   0xba00U
+#define PTP_OFC_MTP_AbstractMultimediaAlbum               0xba01U
+#define PTP_OFC_MTP_AbstractImageAlbum                    0xba02U
+#define PTP_OFC_MTP_AbstractAudioAlbum                    0xba03U
+#define PTP_OFC_MTP_AbstractVideoAlbum                    0xba04U
+#define PTP_OFC_MTP_AbstractAudioVideoPlaylist            0xba05U
+#define PTP_OFC_MTP_AbstractContactGroup                  0xba06U
+#define PTP_OFC_MTP_AbstractMessageFolder                 0xba07U
+#define PTP_OFC_MTP_AbstractChapteredProduction           0xba08U
+#define PTP_OFC_MTP_AbstractAudioPlaylist                 0xba09U
+#define PTP_OFC_MTP_AbstractVideoPlaylist                 0xba0aU
+#define PTP_OFC_MTP_AbstractMediacast                     0xba0bU
+#define PTP_OFC_MTP_WPLPlaylist                           0xba10U
+#define PTP_OFC_MTP_M3UPlaylist                           0xba11U
+#define PTP_OFC_MTP_MPLPlaylist                           0xba12U
+#define PTP_OFC_MTP_ASXPlaylist                           0xba13U
+#define PTP_OFC_MTP_PLSPlaylist                           0xba14U
+#define PTP_OFC_MTP_UndefinedDocument                     0xba80U
+#define PTP_OFC_MTP_AbstractDocument                      0xba81U
+#define PTP_OFC_MTP_XMLDocument                           0xba82U
+#define PTP_OFC_MTP_MSWordDocument                        0xba83U
+#define PTP_OFC_MTP_MHTCompiledHTMLDocument               0xba84U
+#define PTP_OFC_MTP_MSExcelSpreadsheetXLS                 0xba85U
+#define PTP_OFC_MTP_MSPowerpointPresentationPPT           0xba86U
+#define PTP_OFC_MTP_UndefinedMessage                      0xbb00U
+#define PTP_OFC_MTP_AbstractMessage                       0xbb01U
+#define PTP_OFC_MTP_UndefinedContact                      0xbb80U
+#define PTP_OFC_MTP_AbstractContact                       0xbb81U
+#define PTP_OFC_MTP_vCard2                                0xbb82U
+#define PTP_OFC_MTP_vCard3                                0xbb83U
+#define PTP_OFC_MTP_UndefinedCalendarItem                 0xbe00U
+#define PTP_OFC_MTP_AbstractCalendarItem                  0xbe01U
+#define PTP_OFC_MTP_vCalendar1                            0xbe02U
+#define PTP_OFC_MTP_vCalendar2                            0xbe03U
+#define PTP_OFC_MTP_UndefinedWindowsExecutable            0xbe80U
+#define PTP_OFC_MTP_MediaCast                             0xbe81U
+#define PTP_OFC_MTP_Section                               0xbe82U
+
+/* MTP specific Object Properties */
+#define PTP_OPC_StorageID                                 0xDC01U
+#define PTP_OPC_ObjectFormat                              0xDC02U
+#define PTP_OPC_ProtectionStatus                          0xDC03U
+#define PTP_OPC_ObjectSize                                0xDC04U
+#define PTP_OPC_AssociationType                           0xDC05U
+#define PTP_OPC_AssociationDesc                           0xDC06U
+#define PTP_OPC_ObjectFileName                            0xDC07U
+#define PTP_OPC_DateCreated                               0xDC08U
+#define PTP_OPC_DateModified                              0xDC09U
+#define PTP_OPC_Keywords                                  0xDC0AU
+#define PTP_OPC_ParentObject                              0xDC0BU
+#define PTP_OPC_AllowedFolderContents                     0xDC0CU
+#define PTP_OPC_Hidden                                    0xDC0DU
+#define PTP_OPC_SystemObject                              0xDC0EU
+#define PTP_OPC_PersistantUniqueObjectIdentifier          0xDC41U
+#define PTP_OPC_SyncID                                    0xDC42U
+#define PTP_OPC_PropertyBag                               0xDC43U
+#define PTP_OPC_Name                                      0xDC44U
+#define PTP_OPC_CreatedBy                                 0xDC45U
+#define PTP_OPC_Artist                                    0xDC46U
+#define PTP_OPC_DateAuthored                              0xDC47U
+#define PTP_OPC_Description                               0xDC48U
+#define PTP_OPC_URLReference                              0xDC49U
+#define PTP_OPC_LanguageLocale                            0xDC4AU
+#define PTP_OPC_CopyrightInformation                      0xDC4BU
+#define PTP_OPC_Source                                    0xDC4CU
+#define PTP_OPC_OriginLocation                            0xDC4DU
+#define PTP_OPC_DateAdded                                 0xDC4EU
+#define PTP_OPC_NonConsumable                             0xDC4FU
+#define PTP_OPC_CorruptOrUnplayable                       0xDC50U
+#define PTP_OPC_ProducerSerialNumber                      0xDC51U
+#define PTP_OPC_RepresentativeSampleFormat                0xDC81U
+#define PTP_OPC_RepresentativeSampleSize                  0xDC82U
+#define PTP_OPC_RepresentativeSampleHeight                0xDC83U
+#define PTP_OPC_RepresentativeSampleWidth                 0xDC84U
+#define PTP_OPC_RepresentativeSampleDuration              0xDC85U
+#define PTP_OPC_RepresentativeSampleData                  0xDC86U
+#define PTP_OPC_Width                                     0xDC87U
+#define PTP_OPC_Height                                    0xDC88U
+#define PTP_OPC_Duration                                  0xDC89U
+#define PTP_OPC_Rating                                    0xDC8AU
+#define PTP_OPC_Track                                     0xDC8BU
+#define PTP_OPC_Genre                                     0xDC8CU
+#define PTP_OPC_Credits                                   0xDC8DU
+#define PTP_OPC_Lyrics                                    0xDC8EU
+#define PTP_OPC_SubscriptionContentID                     0xDC8FU
+#define PTP_OPC_ProducedBy                                0xDC90U
+#define PTP_OPC_UseCount                                  0xDC91U
+#define PTP_OPC_SkipCount                                 0xDC92U
+#define PTP_OPC_LastAccessed                              0xDC93U
+#define PTP_OPC_ParentalRating                            0xDC94U
+#define PTP_OPC_MetaGenre                                 0xDC95U
+#define PTP_OPC_Composer                                  0xDC96U
+#define PTP_OPC_EffectiveRating                           0xDC97U
+#define PTP_OPC_Subtitle                                  0xDC98U
+#define PTP_OPC_OriginalReleaseDate                       0xDC99U
+#define PTP_OPC_AlbumName                                 0xDC9AU
+#define PTP_OPC_AlbumArtist                               0xDC9BU
+#define PTP_OPC_Mood                                      0xDC9CU
+#define PTP_OPC_DRMStatus                                 0xDC9DU
+#define PTP_OPC_SubDescription                            0xDC9EU
+#define PTP_OPC_IsCropped                                 0xDCD1U
+#define PTP_OPC_IsColorCorrected                          0xDCD2U
+#define PTP_OPC_ImageBitDepth                             0xDCD3U
+#define PTP_OPC_Fnumber                                   0xDCD4U
+#define PTP_OPC_ExposureTime                              0xDCD5U
+#define PTP_OPC_ExposureIndex                             0xDCD6U
+#define PTP_OPC_DisplayName                               0xDCE0U
+#define PTP_OPC_BodyText                                  0xDCE1U
+#define PTP_OPC_Subject                                   0xDCE2U
+#define PTP_OPC_Priority                                  0xDCE3U
+#define PTP_OPC_GivenName                                 0xDD00U
+#define PTP_OPC_MiddleNames                               0xDD01U
+#define PTP_OPC_FamilyName                                0xDD02U
+#define PTP_OPC_Prefix                                    0xDD03U
+#define PTP_OPC_Suffix                                    0xDD04U
+#define PTP_OPC_PhoneticGivenName                         0xDD05U
+#define PTP_OPC_PhoneticFamilyName                        0xDD06U
+#define PTP_OPC_EmailPrimary                              0xDD07U
+#define PTP_OPC_EmailPersonal1                            0xDD08U
+#define PTP_OPC_EmailPersonal2                            0xDD09U
+#define PTP_OPC_EmailBusiness1                            0xDD0AU
+#define PTP_OPC_EmailBusiness2                            0xDD0BU
+#define PTP_OPC_EmailOthers                               0xDD0CU
+#define PTP_OPC_PhoneNumberPrimary                        0xDD0DU
+#define PTP_OPC_PhoneNumberPersonal                       0xDD0EU
+#define PTP_OPC_PhoneNumberPersonal2                      0xDD0FU
+#define PTP_OPC_PhoneNumberBusiness                       0xDD10U
+#define PTP_OPC_PhoneNumberBusiness2                      0xDD11U
+#define PTP_OPC_PhoneNumberMobile                         0xDD12U
+#define PTP_OPC_PhoneNumberMobile2                        0xDD13U
+#define PTP_OPC_FaxNumberPrimary                          0xDD14U
+#define PTP_OPC_FaxNumberPersonal                         0xDD15U
+#define PTP_OPC_FaxNumberBusiness                         0xDD16U
+#define PTP_OPC_PagerNumber                               0xDD17U
+#define PTP_OPC_PhoneNumberOthers                         0xDD18U
+#define PTP_OPC_PrimaryWebAddress                         0xDD19U
+#define PTP_OPC_PersonalWebAddress                        0xDD1AU
+#define PTP_OPC_BusinessWebAddress                        0xDD1BU
+#define PTP_OPC_InstantMessengerAddress                   0xDD1CU
+#define PTP_OPC_InstantMessengerAddress2                  0xDD1DU
+#define PTP_OPC_InstantMessengerAddress3                  0xDD1EU
+#define PTP_OPC_PostalAddressPersonalFull                 0xDD1FU
+#define PTP_OPC_PostalAddressPersonalFullLine1            0xDD20U
+#define PTP_OPC_PostalAddressPersonalFullLine2            0xDD21U
+#define PTP_OPC_PostalAddressPersonalFullCity             0xDD22U
+#define PTP_OPC_PostalAddressPersonalFullRegion           0xDD23U
+#define PTP_OPC_PostalAddressPersonalFullPostalCode       0xDD24U
+#define PTP_OPC_PostalAddressPersonalFullCountry          0xDD25U
+#define PTP_OPC_PostalAddressBusinessFull                 0xDD26U
+#define PTP_OPC_PostalAddressBusinessLine1                0xDD27U
+#define PTP_OPC_PostalAddressBusinessLine2                0xDD28U
+#define PTP_OPC_PostalAddressBusinessCity                 0xDD29U
+#define PTP_OPC_PostalAddressBusinessRegion               0xDD2AU
+#define PTP_OPC_PostalAddressBusinessPostalCode           0xDD2BU
+#define PTP_OPC_PostalAddressBusinessCountry              0xDD2CU
+#define PTP_OPC_PostalAddressOtherFull                    0xDD2DU
+#define PTP_OPC_PostalAddressOtherLine1                   0xDD2EU
+#define PTP_OPC_PostalAddressOtherLine2                   0xDD2FU
+#define PTP_OPC_PostalAddressOtherCity                    0xDD30U
+#define PTP_OPC_PostalAddressOtherRegion                  0xDD31U
+#define PTP_OPC_PostalAddressOtherPostalCode              0xDD32U
+#define PTP_OPC_PostalAddressOtherCountry                 0xDD33U
+#define PTP_OPC_OrganizationName                          0xDD34U
+#define PTP_OPC_PhoneticOrganizationName                  0xDD35U
+#define PTP_OPC_Role                                      0xDD36U
+#define PTP_OPC_Birthdate                                 0xDD37U
+#define PTP_OPC_MessageTo                                 0xDD40U
+#define PTP_OPC_MessageCC                                 0xDD41U
+#define PTP_OPC_MessageBCC                                0xDD42U
+#define PTP_OPC_MessageRead                               0xDD43U
+#define PTP_OPC_MessageReceivedTime                       0xDD44U
+#define PTP_OPC_MessageSender                             0xDD45U
+#define PTP_OPC_ActivityBeginTime                         0xDD50U
+#define PTP_OPC_ActivityEndTime                           0xDD51U
+#define PTP_OPC_ActivityLocation                          0xDD52U
+#define PTP_OPC_ActivityRequiredAttendees                 0xDD54U
+#define PTP_OPC_ActivityOptionalAttendees                 0xDD55U
+#define PTP_OPC_ActivityResources                         0xDD56U
+#define PTP_OPC_ActivityAccepted                          0xDD57U
+#define PTP_OPC_Owner                                     0xDD5DU
+#define PTP_OPC_Editor                                    0xDD5EU
+#define PTP_OPC_Webmaster                                 0xDD5FU
+#define PTP_OPC_URLSource                                 0xDD60U
+#define PTP_OPC_URLDestination                            0xDD61U
+#define PTP_OPC_TimeBookmark                              0xDD62U
+#define PTP_OPC_ObjectBookmark                            0xDD63U
+#define PTP_OPC_ByteBookmark                              0xDD64U
+#define PTP_OPC_LastBuildDate                             0xDD70U
+#define PTP_OPC_TimetoLive                                0xDD71U
+#define PTP_OPC_MediaGUID                                 0xDD72U
+#define PTP_OPC_TotalBitRate                              0xDE91U
+#define PTP_OPC_BitRateType                               0xDE92U
+#define PTP_OPC_SampleRate                                0xDE93U
+#define PTP_OPC_NumberOfChannels                          0xDE94U
+#define PTP_OPC_AudioBitDepth                             0xDE95U
+#define PTP_OPC_ScanDepth                                 0xDE97U
+#define PTP_OPC_AudioWAVECodec                            0xDE99U
+#define PTP_OPC_AudioBitRate                              0xDE9AU
+#define PTP_OPC_VideoFourCCCodec                          0xDE9BU
+#define PTP_OPC_VideoBitRate                              0xDE9CU
+#define PTP_OPC_FramesPerThousandSeconds                  0xDE9DU
+#define PTP_OPC_KeyFrameDistance                          0xDE9EU
+#define PTP_OPC_BufferSize                                0xDE9FU
+#define PTP_OPC_EncodingQuality                           0xDEA0U
+#define PTP_OPC_EncodingProfile                           0xDEA1U
+#define PTP_OPC_BuyFlag                                   0xD901U
+
+/* WiFi Provisioning MTP Extension property codes */
+#define PTP_OPC_WirelessConfigurationFile                 0xB104U
+
+
+/* PTP Association Types */
+#define PTP_AT_Undefined                                  0x0000U
+#define PTP_AT_GenericFolder                              0x0001U
+#define PTP_AT_Album                                      0x0002U
+#define PTP_AT_TimeSequence                               0x0003U
+#define PTP_AT_HorizontalPanoramic                        0x0004U
+#define PTP_AT_VerticalPanoramic                          0x0005U
+#define PTP_AT_2DPanoramic                                0x0006U
+#define PTP_AT_AncillaryData                              0x0007U
+
+
+#define PTP_MAX_HANDLER_NBR                               0x255U
+
+typedef struct {
+    uint32_t n;
+    uint32_t Handler[PTP_MAX_HANDLER_NBR];
+} PTP_ObjectHandles_t;
+
+
+#define PTP_oi_StorageID                                  0U
+#define PTP_oi_ObjectFormat                               4U
+#define PTP_oi_ProtectionStatus                           6U
+#define PTP_oi_ObjectCompressedSize                       8U
+#define PTP_oi_ThumbFormat                                12U
+#define PTP_oi_ThumbCompressedSize                        14U
+#define PTP_oi_ThumbPixWidth                              18U
+#define PTP_oi_ThumbPixHeight                             22U
+#define PTP_oi_ImagePixWidth                              26U
+#define PTP_oi_ImagePixHeight                             30U
+#define PTP_oi_ImageBitDepth                              34U
+#define PTP_oi_ParentObject                               38U
+#define PTP_oi_AssociationType                            42U
+#define PTP_oi_AssociationDesc                            44U
+#define PTP_oi_SequenceNumber                             48U
+#define PTP_oi_filenamelen                                52U
+#define PTP_oi_Filename                                   53U
+
+typedef struct {
+    uint32_t StorageID;
+    uint16_t ObjectFormat;
+    uint16_t ProtectionStatus;
+    /* In the regular objectinfo this is 32bit, but we keep the general object size here
+     that also arrives via other methods and so use 64bit */
+    uint64_t ObjectCompressedSize;
+    uint16_t ThumbFormat;
+    uint32_t ThumbCompressedSize;
+    uint32_t ThumbPixWidth;
+    uint32_t ThumbPixHeight;
+    uint32_t ImagePixWidth;
+    uint32_t ImagePixHeight;
+    uint32_t ImageBitDepth;
+    uint32_t ParentObject;
+    uint16_t AssociationType;
+    uint32_t AssociationDesc;
+    uint32_t SequenceNumber;
+    uint8_t  Filename[PTP_MAX_STR_SIZE];
+    uint32_t CaptureDate;
+    uint32_t ModificationDate;
+    uint8_t  Keywords[PTP_MAX_STR_SIZE];
+} PTP_ObjectInfo_t;
+
+
+/* Object Property Describing Dataset (DevicePropDesc) */
+typedef union  _PTP_PropertyValue_t {
+    char str[PTP_MAX_STR_SIZE];
+    uint8_t u8;
+    int8_t i8;
+    uint16_t u16;
+    int16_t i16;
+    uint32_t u32;
+    int32_t i32;
+    uint64_t u64;
+    int64_t i64;
+    struct array
+    {
+        uint32_t count;
+        union _PTP_PropertyValue_t *v;
+    } a;
+} PTP_PropertyValue_t;
+
+typedef struct {
+    PTP_PropertyValue_t MinimumValue;
+    PTP_PropertyValue_t MaximumValue;
+    PTP_PropertyValue_t StepSize;
+} PTP_PropDescRangeForm_t;
+
+/* Property Describing Dataset, Enum Form */
+typedef struct {
+    uint16_t NumberOfValues;
+    PTP_PropertyValue_t SupportedValue[PTP_SUPPORTED_PROPRIETIES_NBR];
+} PTP_PropDescEnumForm_t;
+
+
+/* (MTP) Object Property pack/unpack */
+#define PTP_opd_ObjectPropertyCode                        0U
+#define PTP_opd_DataType                                  2U
+#define PTP_opd_GetSet                                    4U
+#define PTP_opd_FactoryDefaultValue                       5U
+
+typedef struct {
+    uint16_t    ObjectPropertyCode;
+    uint16_t    DataType;
+    uint8_t     GetSet;
+    PTP_PropertyValue_t FactoryDefaultValue;
+    uint32_t    GroupCode;
+    uint8_t     FormFlag;
+    union
+    {
+        PTP_PropDescEnumForm_t Enum;
+        PTP_PropDescRangeForm_t  Range;
+    } FORM;
+} PTP_ObjectPropDesc_t;
+
+
+/* Metadata lists for MTP operations */
+typedef struct {
+    uint16_t   property;
+    uint16_t   datatype;
+    uint32_t   ObjectHandle;
+    PTP_PropertyValue_t propval;
+} MTP_Properties_t;
+
+
+/* Device Property Form Flag */
+#define PTP_DPFF_None                                     0x00U
+#define PTP_DPFF_Range                                    0x01U
+#define PTP_DPFF_Enumeration                              0x02U
+
+/* Object Property Codes used by MTP (first 3 are same as DPFF codes) */
+#define PTP_OPFF_None                                     0x00U
+#define PTP_OPFF_Range                                    0x01U
+#define PTP_OPFF_Enumeration                              0x02U
+#define PTP_OPFF_DateTime                                 0x03U
+#define PTP_OPFF_FixedLengthArray                         0x04U
+#define PTP_OPFF_RegularExpression                        0x05U
+#define PTP_OPFF_ByteArray                                0x06U
+#define PTP_OPFF_LongString                               0xFFU
+
+
+/* Device Property pack/unpack */
+#define PTP_dpd_DevicePropertyCode                        0U
+#define PTP_dpd_DataType                                  2U
+#define PTP_dpd_GetSet                                    4U
+#define PTP_dpd_FactoryDefaultValue                       5U
+
+/* Device Property Describing Dataset (DevicePropDesc) */
+typedef struct
+{
+    uint16_t  DevicePropertyCode;
+    uint16_t  DataType;
+    uint8_t   GetSet;
+    PTP_PropertyValue_t FactoryDefaultValue;
+    PTP_PropertyValue_t CurrentValue;
+    uint8_t   FormFlag;
+    union
+    {
+        PTP_PropDescEnumForm_t  Enum;
+        PTP_PropDescRangeForm_t  Range;
+    } FORM;
+} PTP_DevicePropDesc_t;
+
+
+/* DataType Codes */
+#define PTP_DTC_UNDEF                                     0x0000U
+#define PTP_DTC_INT8                                      0x0001U
+#define PTP_DTC_UINT8                                     0x0002U
+#define PTP_DTC_INT16                                     0x0003U
+#define PTP_DTC_UINT16                                    0x0004U
+#define PTP_DTC_INT32                                     0x0005U
+#define PTP_DTC_UINT32                                    0x0006U
+#define PTP_DTC_INT64                                     0x0007U
+#define PTP_DTC_UINT64                                    0x0008U
+#define PTP_DTC_INT128                                    0x0009U
+#define PTP_DTC_UINT128                                   0x000AU
+
+#define PTP_DTC_ARRAY_MASK                                0x4000U
+
+#define PTP_DTC_AINT8                                     (PTP_DTC_ARRAY_MASK | PTP_DTC_INT8)
+#define PTP_DTC_AUINT8                                    (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT8)
+#define PTP_DTC_AINT16                                    (PTP_DTC_ARRAY_MASK | PTP_DTC_INT16)
+#define PTP_DTC_AUINT16                                   (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT16)
+#define PTP_DTC_AINT32                                    (PTP_DTC_ARRAY_MASK | PTP_DTC_INT32)
+#define PTP_DTC_AUINT32                                   (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT32)
+#define PTP_DTC_AINT64                                    (PTP_DTC_ARRAY_MASK | PTP_DTC_INT64)
+#define PTP_DTC_AUINT64                                   (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT64)
+#define PTP_DTC_AINT128                                   (PTP_DTC_ARRAY_MASK | PTP_DTC_INT128)
+#define PTP_DTC_AUINT128                                  (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT128)
+
+#define PTP_DTC_STR                                       0xFFFFU
+
+
+/* PTP Event Codes */
+#define PTP_EC_Undefined                                  0x4000U
+#define PTP_EC_CancelTransaction                          0x4001U
+#define PTP_EC_ObjectAdded                                0x4002U
+#define PTP_EC_ObjectRemoved                              0x4003U
+#define PTP_EC_StoreAdded                                 0x4004U
+#define PTP_EC_StoreRemoved                               0x4005U
+#define PTP_EC_DevicePropChanged                          0x4006U
+#define PTP_EC_ObjectInfoChanged                          0x4007U
+#define PTP_EC_DeviceInfoChanged                          0x4008U
+#define PTP_EC_RequestObjectTransfer                      0x4009U
+#define PTP_EC_StoreFull                                  0x400AU
+#define PTP_EC_DeviceReset                                0x400BU
+#define PTP_EC_StorageInfoChanged                         0x400CU
+#define PTP_EC_CaptureComplete                            0x400DU
+#define PTP_EC_UnreportedStatus                           0x400EU
+
+
+void PTP_GetDevicePropValue(USBH_Info_t *phost, uint32_t *offset, uint32_t total, PTP_PropertyValue_t *value, uint16_t datatype);
+
+void PTP_GetString(uint8_t *str, uint8_t *data, uint16_t *len);
+
+uint32_t PTP_GetArray16(uint16_t *array, uint8_t *data, uint32_t offset);
+uint32_t PTP_GetArray32(uint32_t *array, uint8_t *data, uint32_t offset);
+
+void PTP_DecodeDeviceInfo(USBH_Info_t *phost, PTP_DeviceInfo_t *dev_info);
+
+void PTP_DecodeStorageInfo(USBH_Info_t *phost, PTP_StorageInfo_t *storage_info);
+
+void PTP_DecodeObjectInfo(USBH_Info_t *phost, PTP_ObjectInfo_t *object_info);
+
+void PTP_DecodeObjectPropDesc(USBH_Info_t *phost, PTP_ObjectPropDesc_t *opd, uint32_t opdlen);
+
+uint32_t PTP_DecodeObjectPropList(USBH_Info_t *phost, MTP_Properties_t *props, uint32_t len);
+
+
+#define PTP_LE16(addr)  *((uint16_t *)(addr))
+#define PTP_LE32(addr)  *((uint32_t *)(addr))
+#define PTP_LE64(addr)  *((uint64_t *)(addr))
+
+
+#endif  // __USBH_MTP_PTP_H__

+ 23 - 6
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.c

@@ -204,7 +204,8 @@ void USBH_Process(void)
 }
 
 
-uint8_t Cfg_Desc_Buffer[USBH_MAX_CFG_SIZE];
+uint8_t  USBH_Cfg_Desc_Buffer[USBH_MAX_CFG_SIZE];
+uint16_t USBH_Cfg_Desc_Length;
 /******************************************************************************************************************************************
 * 函数名称: USBH_HandleEnum()
 * 功能说明: Handle the USB device enumeration state machine
@@ -264,11 +265,12 @@ USBH_Status USBH_HandleEnum(USBH_Info_t *phost)
         break;
 
     case ENUM_GET_FULL_CFG_DESC:
-        if(USBH_GetDescriptor(phost, USB_DESC_CONFIG, 0, Cfg_Desc_Buffer, phost->Device.Cfg_Desc.wTotalLength) == USBH_OK)
+        if(USBH_GetDescriptor(phost, USB_DESC_CONFIG, 0, USBH_Cfg_Desc_Buffer, phost->Device.Cfg_Desc.wTotalLength) == USBH_OK)
         {
             phost->EnumState = ENUM_GET_VENDOR_STRING_DESC;
 
-            USBH_ParseCfgDesc(phost, Cfg_Desc_Buffer, phost->Device.Cfg_Desc.wTotalLength);
+            USBH_Cfg_Desc_Length = phost->Device.Cfg_Desc.wTotalLength;
+            USBH_ParseCfgDesc(phost, USBH_Cfg_Desc_Buffer, USBH_Cfg_Desc_Length);
 
             if(phost->usr_cb->ConfigDescAvailable)
                 phost->usr_cb->ConfigDescAvailable(&phost->Device.Cfg_Desc, phost->Device.Intf_Desc, phost->Device.Ep_Desc[0]);
@@ -278,13 +280,18 @@ USBH_Status USBH_HandleEnum(USBH_Info_t *phost)
     case ENUM_GET_VENDOR_STRING_DESC:
         if(phost->Device.Dev_Desc.iManufacturer != 0)
         {
-            if(USBH_GetDescriptor(phost, USB_DESC_STRING, phost->Device.Dev_Desc.iManufacturer, (uint8_t *)phost->Device.strVender, sizeof(phost->Device.strVender)) == USBH_OK)
+            USBH_Status stat = USBH_GetDescriptor(phost, USB_DESC_STRING, phost->Device.Dev_Desc.iManufacturer, (uint8_t *)phost->Device.strVender, sizeof(phost->Device.strVender));
+            if(stat == USBH_OK)
             {
                 phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
 
                 if(phost->usr_cb->VendorString)
                     phost->usr_cb->VendorString(phost->Device.strVender);
             }
+            else if(stat == USBH_NOT_SUPPORTED)
+            {
+                phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
+            }
         }
         else
         {
@@ -295,13 +302,18 @@ USBH_Status USBH_HandleEnum(USBH_Info_t *phost)
     case ENUM_GET_PRODUCT_STRING_DESC:
         if(phost->Device.Dev_Desc.iProduct != 0)
         {
-            if(USBH_GetDescriptor(phost, USB_DESC_STRING, phost->Device.Dev_Desc.iProduct, (uint8_t *)phost->Device.strProduct, sizeof(phost->Device.strProduct)) == USBH_OK)
+            USBH_Status stat = USBH_GetDescriptor(phost, USB_DESC_STRING, phost->Device.Dev_Desc.iProduct, (uint8_t *)phost->Device.strProduct, sizeof(phost->Device.strProduct));
+            if(stat == USBH_OK)
             {
                 phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
 
                 if(phost->usr_cb->ProductString)
                     phost->usr_cb->ProductString(phost->Device.strProduct);
             }
+            else if(stat == USBH_NOT_SUPPORTED)
+            {
+                phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
+            }
         }
         else
         {
@@ -312,13 +324,18 @@ USBH_Status USBH_HandleEnum(USBH_Info_t *phost)
     case ENUM_GET_SERIALNUM_STRING_DESC:
         if(phost->Device.Dev_Desc.iSerialNumber != 0)
         {
-            if(USBH_GetDescriptor(phost, USB_DESC_STRING, phost->Device.Dev_Desc.iSerialNumber, (uint8_t *)phost->Device.strSerialNumber, sizeof(phost->Device.strSerialNumber)) == USBH_OK)
+            USBH_Status stat = USBH_GetDescriptor(phost, USB_DESC_STRING, phost->Device.Dev_Desc.iSerialNumber, (uint8_t *)phost->Device.strSerialNumber, sizeof(phost->Device.strSerialNumber));
+            if(stat == USBH_OK)
             {
                 phost->EnumState = ENUM_SET_CONFIGURATION;
 
                 if(phost->usr_cb->SerialNumString)
                     phost->usr_cb->SerialNumString(phost->Device.strSerialNumber);
             }
+            else if(stat == USBH_NOT_SUPPORTED)
+            {
+                phost->EnumState = ENUM_SET_CONFIGURATION;
+            }
         }
         else
         {

+ 2 - 0
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.h

@@ -89,6 +89,8 @@ typedef struct {
     char strSerialNumber[USBH_MAX_STR_SIZE];
 } USBH_Device_t;
 
+extern uint8_t  USBH_Cfg_Desc_Buffer[USBH_MAX_CFG_SIZE];
+extern uint16_t USBH_Cfg_Desc_Length;
 
 struct USBH_Info_T;
 typedef struct {

+ 2 - 2
bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_stdreq.c

@@ -36,7 +36,7 @@ USBH_Status USBH_GetDescriptor(USBH_Info_t *phost, uint8_t type, uint8_t index,
     phost->Ctrl.setup.bRequestType = USB_REQ_D2H | USB_REQ_STANDARD | USB_REQ_TO_DEVICE;
     phost->Ctrl.setup.bRequest = USB_GET_DESCRIPTOR;
     phost->Ctrl.setup.wValue = (type << 8) | index;
-    phost->Ctrl.setup.wIndex = 0;
+    phost->Ctrl.setup.wIndex = (type == USB_DESC_STRING) ? 0x0409 : 0;
     phost->Ctrl.setup.wLength = size;
 
     return USBH_CtrlTransfer(phost, buff, size);
@@ -113,7 +113,7 @@ USBH_Status USBH_SetConfiguration(USBH_Info_t *phost, uint8_t cfg)
 ******************************************************************************************************************************************/
 USBH_Status USBH_SetInterface(USBH_Info_t *phost, uint8_t intf, uint8_t altSetting)
 {
-    phost->Ctrl.setup.bRequestType = USB_REQ_H2D | USB_REQ_STANDARD | USB_REQ_TO_DEVICE;
+    phost->Ctrl.setup.bRequestType = USB_REQ_H2D | USB_REQ_STANDARD | USB_REQ_TO_INTERFACE;
     phost->Ctrl.setup.bRequest = USB_SET_INTERFACE;
     phost->Ctrl.setup.wValue = altSetting;
     phost->Ctrl.setup.wIndex = intf;

+ 2 - 0
bsp/synwit/swm341/rtconfig.h

@@ -6,6 +6,7 @@
 
 /* RT-Thread Kernel */
 
+#define RT_CPUS_NR 1
 #define RT_NAME_MAX 8
 #define RT_ALIGN_SIZE 8
 #define RT_THREAD_PRIORITY_32
@@ -43,6 +44,7 @@
 #define RT_USING_MEMHEAP_AS_HEAP
 #define RT_USING_MEMHEAP_AUTO_BINDING
 #define RT_USING_HEAP
+#define RT_BACKTRACE_LEVEL_MAX_NR 32
 
 /* Kernel Device Object */