From 4018092bafecc5cb4a2d67de86d24d019530c6a1 Mon Sep 17 00:00:00 2001 From: Xian Wu Date: Tue, 12 Dec 2023 18:23:12 +0800 Subject: [PATCH] update CSL library (#8370) --- bsp/synwit/swm320/README.md | 5 - bsp/synwit/swm320/drivers/drv_uart.c | 2 +- .../libraries/CMSIS/DeviceSupport/SWM320.h | 62 +- .../SWM320_StdPeriph_Driver/SWM320_can.c | 195 +-- .../SWM320_StdPeriph_Driver/SWM320_can.h | 40 +- .../SWM320_StdPeriph_Driver/SWM320_gpio.c | 45 +- .../SWM320_StdPeriph_Driver/SWM320_gpio.h | 18 +- .../SWM320_StdPeriph_Driver/SWM320_rtc.c | 228 +-- .../SWM320_StdPeriph_Driver/SWM320_rtc.h | 33 +- .../SWM320_StdPeriph_Driver/SWM320_sdio.c | 5 + .../SWM320_StdPeriph_Driver/SWM320_sdram.c | 4 +- .../SWM320_StdPeriph_Driver/SWM320_sdram.h | 5 +- .../SWM320_StdPeriph_Driver/SWM320_spi.c | 333 +--- .../SWM320_StdPeriph_Driver/SWM320_spi.h | 43 +- .../SWM320_StdPeriph_Driver/SWM320_uart.c | 142 +- .../SWM320_StdPeriph_Driver/SWM320_uart.h | 24 +- bsp/synwit/swm320/rtconfig.h | 2 + bsp/synwit/swm341/README.md | 5 - bsp/synwit/swm341/drivers/drv_sdram.c | 5 +- bsp/synwit/swm341/drivers/drv_uart.c | 2 +- .../libraries/CMSIS/DeviceSupport/SWM341.h | 100 +- .../SWM341_StdPeriph_Driver/SWM341_adc.c | 4 +- .../SWM341_StdPeriph_Driver/SWM341_can.c | 21 +- .../SWM341_StdPeriph_Driver/SWM341_can.h | 20 +- .../SWM341_StdPeriph_Driver/SWM341_dac.c | 7 +- .../SWM341_StdPeriph_Driver/SWM341_dma.c | 125 +- .../SWM341_StdPeriph_Driver/SWM341_dma.h | 23 +- .../SWM341_StdPeriph_Driver/SWM341_dma2d.c | 8 +- .../SWM341_StdPeriph_Driver/SWM341_gpio.c | 47 +- .../SWM341_StdPeriph_Driver/SWM341_gpio.h | 20 +- .../SWM341_StdPeriph_Driver/SWM341_lcd.c | 2 +- .../SWM341_StdPeriph_Driver/SWM341_rtc.c | 232 +-- .../SWM341_StdPeriph_Driver/SWM341_rtc.h | 36 +- .../SWM341_StdPeriph_Driver/SWM341_sdio.c | 277 +++- .../SWM341_StdPeriph_Driver/SWM341_sdio.h | 27 + .../SWM341_StdPeriph_Driver/SWM341_sdram.c | 6 +- .../SWM341_StdPeriph_Driver/SWM341_sdram.h | 44 +- .../SWM341_StdPeriph_Driver/SWM341_sfc.c | 87 +- .../SWM341_StdPeriph_Driver/SWM341_sfc.h | 3 + .../SWM341_StdPeriph_Driver/SWM341_spi.c | 29 +- .../SWM341_StdPeriph_Driver/SWM341_spi.h | 6 +- .../SWM341_StdPeriph_Driver/SWM341_uart.c | 143 +- .../SWM341_StdPeriph_Driver/SWM341_uart.h | 25 +- .../SWM341_StdPeriph_Driver/SWM341_usb.h | 6 + .../SWM341_StdPeriph_Driver/SWM341_usbh.c | 3 +- .../SWM341_StdPeriph_Driver/SWM341_wdt.c | 30 +- .../SWM341_StdPeriph_Driver/SWM341_wdt.h | 1 + .../SWM341_UsbHost_Lib/HID/usbh_hid_keybd.c | 121 +- .../SWM341_UsbHost_Lib/HID/usbh_hid_keybd.h | 15 +- .../SWM341_UsbHost_Lib/MTP/usbh_mtp.c | 1366 +++++++++++++++++ .../SWM341_UsbHost_Lib/MTP/usbh_mtp.h | 153 ++ .../SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.c | 376 +++++ .../SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.h | 758 +++++++++ .../libraries/SWM341_UsbHost_Lib/usbh_core.c | 29 +- .../libraries/SWM341_UsbHost_Lib/usbh_core.h | 2 + .../SWM341_UsbHost_Lib/usbh_stdreq.c | 4 +- bsp/synwit/swm341/rtconfig.h | 2 + 57 files changed, 3836 insertions(+), 1520 deletions(-) create mode 100644 bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.c create mode 100644 bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.h create mode 100644 bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.c create mode 100644 bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.h diff --git a/bsp/synwit/swm320/README.md b/bsp/synwit/swm320/README.md index d1f5d52282..6648822264 100644 --- a/bsp/synwit/swm320/README.md +++ b/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/) diff --git a/bsp/synwit/swm320/drivers/drv_uart.c b/bsp/synwit/swm320/drivers/drv_uart.c index 4ae7f2ea51..7d69e59273 100644 --- a/bsp/synwit/swm320/drivers/drv_uart.c +++ b/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); } diff --git a/bsp/synwit/swm320/libraries/CMSIS/DeviceSupport/SWM320.h b/bsp/synwit/swm320/libraries/CMSIS/DeviceSupport/SWM320.h index dffc3840fa..40ff07db12 100644 --- a/bsp/synwit/swm320/libraries/CMSIS/DeviceSupport/SWM320.h +++ b/bsp/synwit/swm320/libraries/CMSIS/DeviceSupport/SWM320.h @@ -105,6 +105,7 @@ typedef enum IRQn #endif #include +#include #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__ diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.c b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.c index 72b2773547..c97a1bd6ae 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.c +++ b/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() * 功能说明: 查询中断状态 diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.h b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.h index 94ed0bdbc8..07cd9d2b2e 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_can.h +++ b/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__ diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.c b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.c index 7f70fd59cc..be84155e3e 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.c +++ b/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打断) diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.h b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.h index f007d49d0b..06b1f523d7 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_gpio.h +++ b/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__ diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.c b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.c index cbb145055b..66ec09cac1 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.c +++ b/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; } diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.h b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.h index ad038fca7d..ac79db7d10 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_rtc.h +++ b/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__ diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdio.c b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdio.c index f224ea256e..981524e0c5 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdio.c +++ b/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; diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.c b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.c index 1cbd4995c9..0264446063 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.c +++ b/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); } diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.h b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.h index 93ef3ffdf2..9cb7c166f4 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_sdram.h +++ b/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; diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.c b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.c index 9076b57ef6..0ad80eaa3f 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.c +++ b/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_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_INTRXHalfFullEn(SPI_TypeDef * SPIx) +void SPI_INTEn(SPI_TypeDef * SPIx, uint32_t it) { - SPIx->IE |= (0x01 << SPI_IE_RFHF_Pos); + SPIx->IE |= it; } /****************************************************************************************************************************************** -* 函数名称: SPI_INTRXHalfFullDis() -* 功能说明: 接收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_INTRXHalfFullDis(SPI_TypeDef * SPIx) +void SPI_INTDis(SPI_TypeDef * SPIx, uint32_t it) { - SPIx->IE &= ~(0x01 << SPI_IE_RFHF_Pos); + SPIx->IE &= ~it; } /****************************************************************************************************************************************** -* 函数名称: SPI_INTRXHalfFullClr() -* 功能说明: 接收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_INTRXHalfFullClr(SPI_TypeDef * SPIx) +void SPI_INTClr(SPI_TypeDef * SPIx, uint32_t it) { - SPIx->IF = (1 << SPI_IF_RFHF_Pos); + SPIx->IF = it; } /****************************************************************************************************************************************** -* 函数名称: SPI_INTRXHalfFullStat() -* 功能说明: 接收FIFO半满中断状态 +* 函数名称: SPI_INTStat() +* 功能说明: 中断状态查询 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1 -* 输 出: uint32_t 1 接收FIFO达到半满 0 接收FIFO未达到半满 +* 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_INTRXHalfFullStat(SPI_TypeDef * SPIx) +uint32_t SPI_INTStat(SPI_TypeDef * SPIx, uint32_t it) { - 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_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1 -* 输 出: 无 -* 注意事项: 无 -******************************************************************************************************************************************/ -void SPI_INTTXWordCompleteEn(SPI_TypeDef * SPIx) -{ - SPIx->IE |= (0x01 << SPI_IE_WTC_Pos); -} - -/****************************************************************************************************************************************** -* 函数名称: SPI_INTTXWordCompleteDis() -* 功能说明: 发送FIFO字发送完成中断禁止 -* 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1 -* 输 出: 无 -* 注意事项: 无 -******************************************************************************************************************************************/ -void SPI_INTTXWordCompleteDis(SPI_TypeDef * SPIx) -{ - SPIx->IE &= ~(0x01 << SPI_IE_WTC_Pos); -} - -/****************************************************************************************************************************************** -* 函数名称: SPI_INTTXWordCompleteClr() -* 功能说明: 发送FIFO字发送完成中断标志清除 -* 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1 -* 输 出: 无 -* 注意事项: 无 -******************************************************************************************************************************************/ -void SPI_INTTXWordCompleteClr(SPI_TypeDef * SPIx) -{ - SPIx->IF = (1 << SPI_IF_WTC_Pos); -} - -/****************************************************************************************************************************************** -* 函数名称: SPI_INTTXWordCompleteStat() -* 功能说明: 发送FIFO字发送完成中断状态 -* 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1 -* 输 出: uint32_t 1 发送完成中断已发生 0 发送完成中断未发生 -* 注意事项: 无 -******************************************************************************************************************************************/ -uint32_t SPI_INTTXWordCompleteStat(SPI_TypeDef * SPIx) -{ - return (SPIx->IF & SPI_IF_WTC_Msk) ? 1 : 0; + return (SPIx->IF & it) ? 1 : 0; } diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.h b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.h index 1807dbd1e2..a364b3bad9 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_spi.h +++ b/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__ diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.c b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.c index d8cb075354..8984279c81 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.c +++ b/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 -* 输 出: 无 +* 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 中断未发生 * 注意事项: 无 ******************************************************************************************************************************************/ -void UART_INTTXThresholdEn(UART_TypeDef * UARTx) +uint32_t UART_INTStat(UART_TypeDef * UARTx, uint32_t it) { - 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 UART_INTTXDoneStat(UART_TypeDef * UARTx) -{ - 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))); } diff --git a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.h b/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.h index 73a3eacc46..3d4b050e2b 100644 --- a/bsp/synwit/swm320/libraries/SWM320_StdPeriph_Driver/SWM320_uart.h +++ b/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__ diff --git a/bsp/synwit/swm320/rtconfig.h b/bsp/synwit/swm320/rtconfig.h index 6cce825009..787befe375 100644 --- a/bsp/synwit/swm320/rtconfig.h +++ b/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 */ diff --git a/bsp/synwit/swm341/README.md b/bsp/synwit/swm341/README.md index 9840cbc8ba..3429a8862d 100644 --- a/bsp/synwit/swm341/README.md +++ b/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/) diff --git a/bsp/synwit/swm341/drivers/drv_sdram.c b/bsp/synwit/swm341/drivers/drv_sdram.c index 8f22be69fd..32c6deaa32 100644 --- a/bsp/synwit/swm341/drivers/drv_sdram.c +++ b/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; diff --git a/bsp/synwit/swm341/drivers/drv_uart.c b/bsp/synwit/swm341/drivers/drv_uart.c index 40a452dd75..b2f221e1dd 100644 --- a/bsp/synwit/swm341/drivers/drv_uart.c +++ b/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); } diff --git a/bsp/synwit/swm341/libraries/CMSIS/DeviceSupport/SWM341.h b/bsp/synwit/swm341/libraries/CMSIS/DeviceSupport/SWM341.h index 121568bd62..ef4e3e275d 100644 --- a/bsp/synwit/swm341/libraries/CMSIS/DeviceSupport/SWM341.h +++ b/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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_adc.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_adc.c index 8eb527c724..736a1f4f18 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_adc.c +++ b/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)); } /****************************************************************************************************************************************** diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.c index 5037207e0c..f73d394946 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.c +++ b/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中只能读取一次,不能多次读取 diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.h index de1223e61d..0d0018b5c3 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_can.h +++ b/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); diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dac.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dac.c index f20775150c..6a56b578cd 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dac.c +++ b/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 * 输 出: 无 diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.c index ff1f007195..b84dd9f722 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.c +++ b/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)); - if(initStruct->DoneIE) NVIC_EnableIRQ(DMA_IRQn); + DMA_CH_INTClr(chn, initStruct->INTEn); + DMA_CH_INTEn(chn, initStruct->INTEn); + + if(initStruct->INTEn) NVIC_EnableIRQ(DMA_IRQn); } /****************************************************************************************************************************************** @@ -105,49 +126,117 @@ void DMA_CH_Close(uint32_t chn) } /****************************************************************************************************************************************** -* 函数名称: DMA_CH_INTEn() -* 功能说明: DMA中断使能,数据搬运完成后触发中断 +* 函数名称: DMA_CH_SetCount() +* 功能说明: 设置传输 Unit 个数 * 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3 +* uint32_t count 传输 Unit 个数,最大取值0x100000 * 输 出: 无 * 注意事项: 无 ******************************************************************************************************************************************/ -void DMA_CH_INTEn(uint32_t chn) +void DMA_CH_SetCount(uint32_t chn, uint32_t count) { - DMA->IM &= ~(1 << chn); + 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中断使能 +* 输 入: 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, uint32_t it) +{ + 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)))); } diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.h index 7555326084..db9314620a 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma.h +++ b/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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma2d.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma2d.c index f37dbc2a44..3ec88b5128 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_dma2d.c +++ b/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; diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.c index 673f5902d1..368a2611bf 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.c +++ b/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打断) diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.h index 3b4cfd7375..705d4d1ca3 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_gpio.h +++ b/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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_lcd.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_lcd.c index bcae7222e7..cfe0e91a75 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_lcd.c +++ b/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) | diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.c index d2f397b8c7..121ec60730 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.c +++ b/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; } diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.h index 62c9c17b1a..6a6dbf7f1a 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_rtc.h +++ b/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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.c index 0c34b2539c..a8962e1645 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.c +++ b/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; +} diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.h index a9ba1b5bde..d1610bee31 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdio.h +++ b/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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.c index 2c60441473..8c9741a9ef 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.c +++ b/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); diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.h index c306da4aec..f0dcf68d6a 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sdram.h +++ b/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); diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.c index 390351566e..a53853b4cf 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.c +++ b/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(); } diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.h index 5d02430d16..0df602766a 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_sfc.h +++ b/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); diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.c index cb82939dea..226e6d6b37 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.c +++ b/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); - } -} diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.h index a57ae14fb9..a7e733c6db 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_spi.h +++ b/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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.c index 610de573f8..7fcd618279 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.c +++ b/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_INTClr() +* 功能说明: 中断标志清除 * 输 入: UART_TypeDef * UARTx 指定要被设置的UART串口,有效值包括UART0、UART1、UART2、UART3 +* uint32_t it interrupt type,有效值有 UART_IT_RX_TOUT * 输 出: 无 * 注意事项: 无 ******************************************************************************************************************************************/ -void UART_INTTXThresholdEn(UART_TypeDef * UARTx) +void UART_INTClr(UART_TypeDef * UARTx, uint32_t it) { - UARTx->CTRL |= (0x01 << UART_CTRL_TXIE_Pos); + if(it & UART_IT_RX_TOUT) + UARTx->TOCR |= UART_TOCR_IFCLR_Msk; } /****************************************************************************************************************************************** -* 函数名称: UART_INTTXThresholdDis() -* 功能说明: 当TX FIFO中数据个数 <= TXThreshold时 不触发中断 +* 函数名称: UART_INTStat() +* 功能说明: 中断状态查询 * 输 入: 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 及其“或” +* 输 出: uint32_t 1 中断已发生 0 中断未发生 * 注意事项: 无 ******************************************************************************************************************************************/ -void UART_INTTXThresholdDis(UART_TypeDef * UARTx) +uint32_t UART_INTStat(UART_TypeDef * UARTx, uint32_t it) { - 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 UART_INTTXDoneStat(UART_TypeDef * UARTx) -{ - 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))); } diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.h index 6ddb79b2ee..96bbeda416 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_uart.h +++ b/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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usb.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usb.h index e9566f406d..eef8780bba 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usb.h +++ b/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 diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usbh.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usbh.c index 6a643c5123..b77854d133 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_usbh.c +++ b/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; } diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.c b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.c index 253d17ad74..7f583ccb25 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.c +++ b/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; } /****************************************************************************************************************************************** diff --git a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.h b/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.h index 1dca1e2b99..5e65d4c25c 100644 --- a/bsp/synwit/swm341/libraries/SWM341_StdPeriph_Driver/SWM341_wdt.h +++ b/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,停止倒计时 diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.c b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.c index cf1b548b20..7e817b1757 100644 --- a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.c +++ b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.c @@ -18,6 +18,7 @@ * * COPYRIGHT 2012 Synwit Technology *******************************************************************************************************************************************/ +#include #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) +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; +} + + +__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); } diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.h b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.h index 1c4eb35951..df37b0de57 100644 --- a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.h +++ b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/HID/usbh_hid_keybd.h @@ -4,11 +4,24 @@ #include +#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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.c b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.c new file mode 100644 index 0000000000..2b78377dd4 --- /dev/null +++ b/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 +#include +#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) +{ +} diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.h b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp.h new file mode 100644 index 0000000000..f74a6e1f77 --- /dev/null +++ b/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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.c b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.c new file mode 100644 index 0000000000..42fed1eb28 --- /dev/null +++ b/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 +#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; +} diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.h b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/MTP/usbh_mtp_ptp.h new file mode 100644 index 0000000000..aee37df260 --- /dev/null +++ b/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 + +#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__ diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.c b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.c index 3d488cf0b3..3dcfdd234e 100644 --- a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.c +++ b/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 { diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.h b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.h index e2d0994a6f..8d9435fe17 100644 --- a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_core.h +++ b/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 { diff --git a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_stdreq.c b/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_stdreq.c index 08e7bc6cfe..bb8f53ffe8 100644 --- a/bsp/synwit/swm341/libraries/SWM341_UsbHost_Lib/usbh_stdreq.c +++ b/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; diff --git a/bsp/synwit/swm341/rtconfig.h b/bsp/synwit/swm341/rtconfig.h index 939292c7d2..f247abd3b7 100644 --- a/bsp/synwit/swm341/rtconfig.h +++ b/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 */