summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2022-06-14 22:05:48 +0800
committersakumisu <[email protected]>2022-06-14 22:05:48 +0800
commit8d7ef730a2577b26d23588130bdae4637cb799ca (patch)
tree101d6abff9572d6b4b45dac8b90b9f0b46007359
parentf761392ed1680afb3b6a5088138a72b0c29162b8 (diff)
refactor dwc2 port
-rw-r--r--SConscript22
-rw-r--r--demo/stm32/usb_device/stm32f429igt6/Core/Inc/usb_config.h26
-rw-r--r--demo/stm32/usb_device/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s2
-rw-r--r--demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx82
-rw-r--r--demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx23
-rw-r--r--demo/stm32/usb_host/stm32f429igt6/Core/Inc/usb_config.h62
-rw-r--r--demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c49
-rw-r--r--demo/stm32/usb_host/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s2
-rw-r--r--demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx70
-rw-r--r--demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx17
-rw-r--r--port/dwc2/README.md (renamed from port/synopsys/README.md)0
-rw-r--r--port/dwc2/usb_dc_dwc2.c917
-rw-r--r--port/dwc2/usb_dwc2_reg.h (renamed from port/synopsys/usb_synopsys_reg.h)224
-rw-r--r--port/dwc2/usb_hc_dwc2.c1389
-rw-r--r--port/synopsys/usb_dc_synopsys.c696
-rw-r--r--port/synopsys/usb_hc_synopsys.c928
16 files changed, 2505 insertions, 2004 deletions
diff --git a/SConscript b/SConscript
index d74326d4..2ce805bf 100644
--- a/SConscript
+++ b/SConscript
@@ -5,15 +5,12 @@ path = [cwd + '/common']
path += [cwd + '/core']
src = []
-CPPDEFINES = ['-Dprintf=rt_kprintf']
-
# USB DEVICE
if GetDepend(['PKG_CHERRYUSB_DEVICE']):
src += Glob('core/usbd_core.c')
+
if GetDepend(['PKG_CHERRYUSB_DEVICE_HS']):
CPPDEFINES+=['CONFIG_USB_HS']
- elif GetDepend(['PKG_CHERRYUSB_DEVICE_HS_IN_FULL']):
- CPPDEFINES += ['CONFIG_USB_HS_IN_FULL']
if GetDepend(['PKG_CHERRYUSB_DEVICE_CDC']):
path += [cwd + '/class/cdc']
@@ -49,16 +46,20 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
if GetDepend(['PKG_CHERRYUSB_DEVICE_MSC_TEMPLATE']):
src += Glob('demo/msc_ram_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_AUDIO_V1_TEMPLATE']):
- src += Glob('demo/audio_v1_mic_speaker_dualchan_template.c')
+ src += Glob('demo/audio_v1_mic_speaker_multichan_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_AUDIO_V2_TEMPLATE']):
src += Glob('demo/audio_v2_mic_speaker_multichan_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_VIDEO_TEMPLATE']):
src += Glob('demo/video_static_mjpeg_template.c')
- if GetDepend(['PKG_CHERRYUSB_DEVICE_FSDEV_STM32']):
+ if GetDepend(['PKG_CHERRYUSB_DEVICE_FSDEV']):
src += Glob('port/fsdev/usb_dc_fsdev.c')
- if GetDepend(['PKG_CHERRYUSB_DEVICE_SYNOPSYS_STM32']):
- src += Glob('port/synopsys/usb_dc_synopsys.c')
+ if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2']):
+ src += Glob('port/synopsys/usb_dc_dwc2.c')
+ if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_PORT_FS']):
+ CPPDEFINES += ['CONFIG_USB_DWC2_PORT=FS_PORT']
+ elif GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_PORT_HS']):
+ CPPDEFINES += ['CONFIG_USB_DWC2_PORT=HS_PORT']
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB']):
src += Glob('port/musb/usb_dc_musb.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_SUNXI']):
@@ -88,8 +89,9 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
src += Glob('class/hub/usbh_hub.c')
CPPDEFINES += ['CONFIG_USBHOST_HUB']
- if GetDepend(['PKG_CHERRYUSB_HOST_SYNOPSYS_STM32']):
- src += Glob('port/synopsys/usb_hc_synopsys.c')
+ if GetDepend(['PKG_CHERRYUSB_HOST_DWC2']):
+ src += Glob('port/synopsys/usb_hc_dwc2.c')
+ CPPDEFINES += ['CONFIG_USBHOST_HIGH_WORKQ']
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB']):
src += Glob('port/musb/usb_hc_musb.c')
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_SUNXI']):
diff --git a/demo/stm32/usb_device/stm32f429igt6/Core/Inc/usb_config.h b/demo/stm32/usb_device/stm32f429igt6/Core/Inc/usb_config.h
index 59dd164b..39c77df6 100644
--- a/demo/stm32/usb_device/stm32f429igt6/Core/Inc/usb_config.h
+++ b/demo/stm32/usb_device/stm32f429igt6/Core/Inc/usb_config.h
@@ -1,6 +1,17 @@
#ifndef _USB_CONFIG_H
#define _USB_CONFIG_H
+/* USB common Configuration */
+#ifndef CONFIG_USB_DBG_LEVEL
+#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
+#endif
+
+#ifndef CONFIG_USB_PRINTF
+#define CONFIG_USB_PRINTF printf
+#endif
+
+#define CONFIG_USB_PRINTF_COLOR_ENABLE
+
/* USB DEVICE Configuration */
/* core */
#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
@@ -15,6 +26,9 @@
#define CONFIG_USBDEV_TEST_MODE 0
#endif
+/* cdc class */
+// #define CONFIG_USBDEV_CDC_ACM_UART
+
/* msc class */
#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
@@ -28,6 +42,18 @@
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
#endif
+// #define CONFIG_USBDEV_MSC_THREAD
+
+#ifdef CONFIG_USBDEV_MSC_THREAD
+#ifndef CONFIG_USBDEV_MSC_STACKSIZE
+#define CONFIG_USBDEV_MSC_STACKSIZE 2048
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_PRIO
+#define CONFIG_USBDEV_MSC_PRIO 4
+#endif
+#endif
+
/* audio class */
#ifndef CONFIG_USBDEV_AUDIO_VERSION
#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
diff --git a/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s b/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s
index 6d04068b..5943e2be 100644
--- a/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s
+++ b/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s
@@ -41,7 +41,7 @@ __initial_sp
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
-Heap_Size EQU 0x200
+Heap_Size EQU 0x1000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
diff --git a/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx b/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx
index 646cbe21..767de2d5 100644
--- a/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx
+++ b/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx
@@ -103,7 +103,7 @@
<bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf>
- <nTsel>6</nTsel>
+ <nTsel>3</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@@ -114,7 +114,7 @@
<tDlgDll></tDlgDll>
<tDlgPa></tDlgPa>
<tIfile></tIfile>
- <pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
+ <pMon>BIN\CMSIS_AGDI.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
@@ -135,12 +135,12 @@
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
- <Name>(105=-1,-1,-1,-1,0)</Name>
+ <Name></Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>CMSIS_AGDI</Key>
- <Name>-X"Fire CMSIS-DAP" -UFS-00001418 -O239 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F429IGTx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name>
+ <Name>-X"Fire CMSIS-DAP" -UFS-00001418 -O239 -S10 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F429IGTx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
@@ -157,7 +157,23 @@
<Bp>
<Number>0</Number>
<Type>0</Type>
- <LineNumber>525</LineNumber>
+ <LineNumber>537</LineNumber>
+ <EnabledFlag>1</EnabledFlag>
+ <Address>0</Address>
+ <ByteObject>0</ByteObject>
+ <HtxType>0</HtxType>
+ <ManyObjects>0</ManyObjects>
+ <SizeOfObject>0</SizeOfObject>
+ <BreakByAccess>0</BreakByAccess>
+ <BreakIfRCount>0</BreakIfRCount>
+ <Filename>..\..\..\..\..\core\usbd_core.c</Filename>
+ <ExecCommand></ExecCommand>
+ <Expression></Expression>
+ </Bp>
+ <Bp>
+ <Number>1</Number>
+ <Type>0</Type>
+ <LineNumber>383</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>0</Address>
<ByteObject>0</ByteObject>
@@ -166,7 +182,7 @@
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>0</BreakIfRCount>
- <Filename>C:\Users\lvjiazhen\Desktop\usb_stack\demo\port\synopsys\usb_dc_synopsys.c</Filename>
+ <Filename>..\..\..\..\..\core\usbd_core.c</Filename>
<ExecCommand></ExecCommand>
<Expression></Expression>
</Bp>
@@ -245,7 +261,7 @@
<Group>
<GroupName>Application/User/Core</GroupName>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -497,53 +513,17 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
- <File>
- <GroupNumber>3</GroupNumber>
- <FileNumber>22</FileNumber>
- <FileType>1</FileType>
- <tvExp>0</tvExp>
- <tvExpOptDlg>0</tvExpOptDlg>
- <bDave2>0</bDave2>
- <PathWithFileName>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c</PathWithFileName>
- <FilenameWithoutPath>stm32f4xx_hal_pcd.c</FilenameWithoutPath>
- <RteFlg>0</RteFlg>
- <bShared>0</bShared>
- </File>
- <File>
- <GroupNumber>3</GroupNumber>
- <FileNumber>23</FileNumber>
- <FileType>1</FileType>
- <tvExp>0</tvExp>
- <tvExpOptDlg>0</tvExpOptDlg>
- <bDave2>0</bDave2>
- <PathWithFileName>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c</PathWithFileName>
- <FilenameWithoutPath>stm32f4xx_hal_pcd_ex.c</FilenameWithoutPath>
- <RteFlg>0</RteFlg>
- <bShared>0</bShared>
- </File>
- <File>
- <GroupNumber>3</GroupNumber>
- <FileNumber>24</FileNumber>
- <FileType>1</FileType>
- <tvExp>0</tvExp>
- <tvExpOptDlg>0</tvExpOptDlg>
- <bDave2>0</bDave2>
- <PathWithFileName>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c</PathWithFileName>
- <FilenameWithoutPath>stm32f4xx_ll_usb.c</FilenameWithoutPath>
- <RteFlg>0</RteFlg>
- <bShared>0</bShared>
- </File>
</Group>
<Group>
<GroupName>Drivers/CMSIS</GroupName>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>4</GroupNumber>
- <FileNumber>25</FileNumber>
+ <FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -563,7 +543,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>5</GroupNumber>
- <FileNumber>26</FileNumber>
+ <FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -575,7 +555,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
- <FileNumber>27</FileNumber>
+ <FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -587,13 +567,13 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
- <FileNumber>28</FileNumber>
+ <FileNumber>25</FileNumber>
<FileType>1</FileType>
- <tvExp>0</tvExp>
+ <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
- <PathWithFileName>..\..\..\..\..\port\synopsys\usb_dc_synopsys.c</PathWithFileName>
- <FilenameWithoutPath>usb_dc_synopsys.c</FilenameWithoutPath>
+ <PathWithFileName>..\..\..\..\..\port\dwc2\usb_dc_dwc2.c</PathWithFileName>
+ <FilenameWithoutPath>usb_dc_dwc2.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
diff --git a/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx b/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx
index 36eafaf4..7c6e4b84 100644
--- a/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx
+++ b/demo/stm32/usb_device/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx
@@ -338,9 +338,9 @@
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
- <Define>USE_HAL_DRIVER,STM32F429xx,CONFIG_USB_HS_IN_FULL</Define>
+ <Define>USE_HAL_DRIVER,STM32F429xx,CONFIG_USB_DWC2_PORT=HS_PORT</Define>
<Undefine></Undefine>
- <IncludePath>../Core/Inc; ../Drivers/STM32F4xx_HAL_Driver/Inc; ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy; ../Drivers/CMSIS/Device/ST/STM32F4xx/Include; ../Drivers/CMSIS/Include; ..\..\..\..\..\class\cdc; ..\..\..\..\..\core; ..\..\..\..\..\common</IncludePath>
+ <IncludePath>../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\class\cdc;..\..\..\..\..\core;..\..\..\..\..\common;..\..\..\..\..\class\video;..\..\..\..\..\class\msc;..\..\..\..\..\class\audio</IncludePath>
</VariousControls>
</Cads>
<Aads>
@@ -550,21 +550,6 @@
<FileType>1</FileType>
<FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c</FilePath>
</File>
- <File>
- <FileName>stm32f4xx_hal_pcd.c</FileName>
- <FileType>1</FileType>
- <FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c</FilePath>
- </File>
- <File>
- <FileName>stm32f4xx_hal_pcd_ex.c</FileName>
- <FileType>1</FileType>
- <FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c</FilePath>
- </File>
- <File>
- <FileName>stm32f4xx_ll_usb.c</FileName>
- <FileType>1</FileType>
- <FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c</FilePath>
- </File>
</Files>
</Group>
<Group>
@@ -591,9 +576,9 @@
<FilePath>..\..\..\..\..\core\usbd_core.c</FilePath>
</File>
<File>
- <FileName>usb_dc_synopsys.c</FileName>
+ <FileName>usb_dc_dwc2.c</FileName>
<FileType>1</FileType>
- <FilePath>..\..\..\..\..\port\synopsys\usb_dc_synopsys.c</FilePath>
+ <FilePath>..\..\..\..\..\port\dwc2\usb_dc_dwc2.c</FilePath>
</File>
</Files>
</Group>
diff --git a/demo/stm32/usb_host/stm32f429igt6/Core/Inc/usb_config.h b/demo/stm32/usb_host/stm32f429igt6/Core/Inc/usb_config.h
index 86c786cc..39c77df6 100644
--- a/demo/stm32/usb_host/stm32f429igt6/Core/Inc/usb_config.h
+++ b/demo/stm32/usb_host/stm32f429igt6/Core/Inc/usb_config.h
@@ -1,7 +1,67 @@
#ifndef _USB_CONFIG_H
#define _USB_CONFIG_H
+/* USB common Configuration */
+#ifndef CONFIG_USB_DBG_LEVEL
+#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
+#endif
+
+#ifndef CONFIG_USB_PRINTF
+#define CONFIG_USB_PRINTF printf
+#endif
+
+#define CONFIG_USB_PRINTF_COLOR_ENABLE
+
/* USB DEVICE Configuration */
+/* core */
+#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
+#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
+#endif
+
+#ifndef CONFIG_USBDEV_DESC_CHECK
+#define CONFIG_USBDEV_DESC_CHECK 0
+#endif
+
+#ifndef CONFIG_USBDEV_TEST_MODE
+#define CONFIG_USBDEV_TEST_MODE 0
+#endif
+
+/* cdc class */
+// #define CONFIG_USBDEV_CDC_ACM_UART
+
+/* msc class */
+#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
+#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
+#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
+#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
+#endif
+
+// #define CONFIG_USBDEV_MSC_THREAD
+
+#ifdef CONFIG_USBDEV_MSC_THREAD
+#ifndef CONFIG_USBDEV_MSC_STACKSIZE
+#define CONFIG_USBDEV_MSC_STACKSIZE 2048
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_PRIO
+#define CONFIG_USBDEV_MSC_PRIO 4
+#endif
+#endif
+
+/* audio class */
+#ifndef CONFIG_USBDEV_AUDIO_VERSION
+#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
+#endif
+
+#ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL
+#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 2
+#endif
/* USB HOST Configuration */
#ifndef CONFIG_USBHOST_RHPORTS
@@ -69,4 +129,4 @@
#define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
// #define CONFIG_USB_EHCI_CONFIGFLAG
-#endif \ No newline at end of file
+#endif
diff --git a/demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c b/demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c
index e9fe153f..9edcc26d 100644
--- a/demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c
+++ b/demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c
@@ -45,7 +45,7 @@
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
-//HCD_HandleTypeDef hhcd_USB_OTG_HS;
+HCD_HandleTypeDef hhcd_USB_OTG_HS;
/* USER CODE BEGIN PV */
@@ -68,6 +68,27 @@ int fputc(int ch, FILE *f)
return ch;
}
+void usb_hc_low_level_init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /**USB_OTG_HS GPIO Configuration
+ PB14 ------> USB_OTG_HS_DM
+ PB15 ------> USB_OTG_HS_DP
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
+ /* USB_OTG_HS interrupt Init */
+ HAL_NVIC_SetPriority(OTG_HS_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
+}
/* USER CODE END 0 */
/**
@@ -209,19 +230,19 @@ static void MX_USB_OTG_HS_HCD_Init(void)
/* USER CODE BEGIN USB_OTG_HS_Init 1 */
/* USER CODE END USB_OTG_HS_Init 1 */
-// hhcd_USB_OTG_HS.Instance = USB_OTG_HS;
-// hhcd_USB_OTG_HS.Init.Host_channels = 12;
-// hhcd_USB_OTG_HS.Init.speed = HCD_SPEED_FULL;
-// hhcd_USB_OTG_HS.Init.dma_enable = DISABLE;
-// hhcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY;
-// hhcd_USB_OTG_HS.Init.Sof_enable = DISABLE;
-// hhcd_USB_OTG_HS.Init.low_power_enable = DISABLE;
-// hhcd_USB_OTG_HS.Init.vbus_sensing_enable = DISABLE;
-// hhcd_USB_OTG_HS.Init.use_external_vbus = DISABLE;
-// if (HAL_HCD_Init(&hhcd_USB_OTG_HS) != HAL_OK)
-// {
-// Error_Handler();
-// }
+ hhcd_USB_OTG_HS.Instance = USB_OTG_HS;
+ hhcd_USB_OTG_HS.Init.Host_channels = 12;
+ hhcd_USB_OTG_HS.Init.speed = HCD_SPEED_FULL;
+ hhcd_USB_OTG_HS.Init.dma_enable = DISABLE;
+ hhcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY;
+ hhcd_USB_OTG_HS.Init.Sof_enable = DISABLE;
+ hhcd_USB_OTG_HS.Init.low_power_enable = DISABLE;
+ hhcd_USB_OTG_HS.Init.vbus_sensing_enable = DISABLE;
+ hhcd_USB_OTG_HS.Init.use_external_vbus = DISABLE;
+ if (HAL_HCD_Init(&hhcd_USB_OTG_HS) != HAL_OK)
+ {
+ Error_Handler();
+ }
/* USER CODE BEGIN USB_OTG_HS_Init 2 */
/* USER CODE END USB_OTG_HS_Init 2 */
diff --git a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s
index ffaf8b3b..75b5b4d5 100644
--- a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s
+++ b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/startup_stm32f429xx.s
@@ -30,7 +30,7 @@
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
-Stack_Size EQU 0x400
+Stack_Size EQU 0x1000
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
diff --git a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx
index c7398ea8..6ce3cf8d 100644
--- a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx
+++ b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx
@@ -153,39 +153,17 @@
<Name>-U066EFF555453774987091527 -O2287 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F429IGTx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
- <Breakpoint>
- <Bp>
- <Number>0</Number>
- <Type>0</Type>
- <LineNumber>493</LineNumber>
- <EnabledFlag>1</EnabledFlag>
- <Address>0</Address>
- <ByteObject>0</ByteObject>
- <HtxType>0</HtxType>
- <ManyObjects>0</ManyObjects>
- <SizeOfObject>0</SizeOfObject>
- <BreakByAccess>0</BreakByAccess>
- <BreakIfRCount>0</BreakIfRCount>
- <Filename>..\..\..\..\..\core\usbh_core.c</Filename>
- <ExecCommand></ExecCommand>
- <Expression></Expression>
- </Bp>
- </Breakpoint>
+ <Breakpoint/>
<WatchWindow1>
<Ww>
<count>0</count>
<WinNumber>1</WinNumber>
- <ItemText>intf</ItemText>
+ <ItemText>gint_status</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
- <ItemText>setup</ItemText>
- </Ww>
- <Ww>
- <count>2</count>
- <WinNumber>1</WinNumber>
- <ItemText>hport</ItemText>
+ <ItemText>chan_int</ItemText>
</Ww>
</WatchWindow1>
<Tracepoint>
@@ -242,7 +220,7 @@
<Group>
<GroupName>Application/MDK-ARM</GroupName>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -262,7 +240,7 @@
<Group>
<GroupName>Application/User/Core</GroupName>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -330,7 +308,7 @@
<Group>
<GroupName>Drivers/STM32F4xx_HAL_Driver</GroupName>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -574,7 +552,7 @@
<Group>
<GroupName>FreeRTOS</GroupName>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -678,7 +656,7 @@
<Group>
<GroupName>CherryUSB</GroupName>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -734,11 +712,11 @@
<GroupNumber>6</GroupNumber>
<FileNumber>38</FileNumber>
<FileType>1</FileType>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
- <PathWithFileName>..\..\..\..\..\class\hub\usbh_hub.c</PathWithFileName>
- <FilenameWithoutPath>usbh_hub.c</FilenameWithoutPath>
+ <PathWithFileName>..\..\..\..\..\osal\usb_osal_freertos.c</PathWithFileName>
+ <FilenameWithoutPath>usb_osal_freertos.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
@@ -749,8 +727,8 @@
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
- <PathWithFileName>..\..\..\..\..\osal\usb_osal_freertos.c</PathWithFileName>
- <FilenameWithoutPath>usb_osal_freertos.c</FilenameWithoutPath>
+ <PathWithFileName>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</PathWithFileName>
+ <FilenameWithoutPath>usb_hc_dwc2.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
@@ -766,18 +744,6 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
- <File>
- <GroupNumber>6</GroupNumber>
- <FileNumber>41</FileNumber>
- <FileType>1</FileType>
- <tvExp>0</tvExp>
- <tvExpOptDlg>0</tvExpOptDlg>
- <bDave2>0</bDave2>
- <PathWithFileName>..\..\..\..\..\port\synopsys\usb_hc_synopsys.c</PathWithFileName>
- <FilenameWithoutPath>usb_hc_synopsys.c</FilenameWithoutPath>
- <RteFlg>0</RteFlg>
- <bShared>0</bShared>
- </File>
</Group>
<Group>
@@ -788,7 +754,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>7</GroupNumber>
- <FileNumber>42</FileNumber>
+ <FileNumber>41</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -800,7 +766,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
- <FileNumber>43</FileNumber>
+ <FileNumber>42</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -812,7 +778,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
- <FileNumber>44</FileNumber>
+ <FileNumber>43</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -824,7 +790,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
- <FileNumber>45</FileNumber>
+ <FileNumber>44</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -836,7 +802,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
- <FileNumber>46</FileNumber>
+ <FileNumber>45</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
diff --git a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx
index b3a47206..872fcc6f 100644
--- a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx
+++ b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx
@@ -314,7 +314,7 @@
</ArmAdsMisc>
<Cads>
<interw>1</interw>
- <Optim>3</Optim>
+ <Optim>1</Optim>
<oTime>0</oTime>
<SplitLS>0</SplitLS>
<OneElfS>1</OneElfS>
@@ -338,7 +338,7 @@
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
- <Define>USE_HAL_DRIVER,STM32F429xx,CONFIG_USB_HS_IN_FULL,CONFIG_USBHOST_HUB</Define>
+ <Define>USE_HAL_DRIVER,STM32F429xx,CONFIG_USBHOST_HIGH_WORKQ</Define>
<Undefine></Undefine>
<IncludePath>../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\common;..\..\..\..\..\core;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hub;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\osal;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F;..\..\..\..\..\third_party\fatfs-0.14\source</IncludePath>
</VariousControls>
@@ -595,24 +595,19 @@
<FilePath>..\..\..\..\..\class\hid\usbh_hid.c</FilePath>
</File>
<File>
- <FileName>usbh_hub.c</FileName>
- <FileType>1</FileType>
- <FilePath>..\..\..\..\..\class\hub\usbh_hub.c</FilePath>
- </File>
- <File>
<FileName>usb_osal_freertos.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\..\..\..\osal\usb_osal_freertos.c</FilePath>
</File>
<File>
- <FileName>usb_workq.c</FileName>
+ <FileName>usb_hc_dwc2.c</FileName>
<FileType>1</FileType>
- <FilePath>..\..\..\..\..\osal\usb_workq.c</FilePath>
+ <FilePath>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</FilePath>
</File>
<File>
- <FileName>usb_hc_synopsys.c</FileName>
+ <FileName>usb_workq.c</FileName>
<FileType>1</FileType>
- <FilePath>..\..\..\..\..\port\synopsys\usb_hc_synopsys.c</FilePath>
+ <FilePath>..\..\..\..\..\osal\usb_workq.c</FilePath>
</File>
</Files>
</Group>
diff --git a/port/synopsys/README.md b/port/dwc2/README.md
index d0bc3df6..d0bc3df6 100644
--- a/port/synopsys/README.md
+++ b/port/dwc2/README.md
diff --git a/port/dwc2/usb_dc_dwc2.c b/port/dwc2/usb_dc_dwc2.c
new file mode 100644
index 00000000..733b5391
--- /dev/null
+++ b/port/dwc2/usb_dc_dwc2.c
@@ -0,0 +1,917 @@
+#include "usbd_core.h"
+#include "usb_dwc2_reg.h"
+
+#define FS_PORT 0
+#define HS_PORT 1
+
+#ifndef CONFIG_USB_DWC2_PORT
+#error "please select CONFIG_USB_DWC2_PORT with FS_PORT or HS_PORT"
+#endif
+
+#if CONFIG_USB_DWC2_PORT == FS_PORT
+#ifndef USBD_IRQHandler
+#define USBD_IRQHandler OTG_FS_IRQHandler
+#endif
+
+#ifndef USB_BASE
+#ifdef STM32H7
+#define USB_BASE (0x40080000UL)
+#else
+#define USB_BASE (0x50000000UL)
+#endif
+#endif
+
+#define USB_RAM_SIZE 1280 /* define with minimum value*/
+
+/*FIFO sizes in bytes (total available memory for FIFOs is 1.25KB )*/
+#ifndef CONFIG_USB_DWC2_RX_FIFO_SIZE
+#define CONFIG_USB_DWC2_RX_FIFO_SIZE (512)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX0_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX1_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (128)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX2_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (128)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX3_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (128)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX4_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (128)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX5_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (128)
+#endif
+
+#else
+
+#ifndef USBD_IRQHandler
+#define USBD_IRQHandler OTG_HS_IRQHandler
+#endif
+
+#ifndef USB_BASE
+#define USB_BASE (0x40040000UL)
+#endif
+
+#define USB_RAM_SIZE 4096 /* define with minimum value*/
+
+/*FIFO sizes in bytes (total available memory for FIFOs is 4KB )*/
+#ifndef CONFIG_USB_DWC2_RX_FIFO_SIZE
+#define CONFIG_USB_DWC2_RX_FIFO_SIZE (1024)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX0_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (512)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX1_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX2_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (512)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX3_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (512)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX4_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (256)
+#endif
+
+#ifndef CONFIG_USB_DWC2_TX5_FIFO_SIZE
+#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (256)
+#endif
+
+#endif
+
+#ifndef USB_NUM_BIDIR_ENDPOINTS
+#define USB_NUM_BIDIR_ENDPOINTS 6 /* define with minimum value*/
+#endif
+
+#define USB_OTG_GLB ((USB_OTG_GlobalTypeDef *)(USB_BASE))
+#define USB_OTG_DEV ((USB_OTG_DeviceTypeDef *)(USB_BASE + USB_OTG_DEVICE_BASE))
+#define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)USB_BASE + USB_OTG_PCGCCTL_BASE)
+#define USB_OTG_INEP(i) ((USB_OTG_INEndpointTypeDef *)(USB_BASE + USB_OTG_IN_ENDPOINT_BASE + ((i)*USB_OTG_EP_REG_SIZE)))
+#define USB_OTG_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)(USB_BASE + USB_OTG_OUT_ENDPOINT_BASE + ((i)*USB_OTG_EP_REG_SIZE)))
+#define USB_OTG_FIFO(i) *(__IO uint32_t *)(USB_BASE + USB_OTG_FIFO_BASE + ((i)*USB_OTG_FIFO_SIZE))
+
+extern uint32_t SystemCoreClock;
+
+/* Endpoint state */
+struct dwc2_ep_state {
+ /** Endpoint max packet size */
+ uint16_t ep_mps;
+ /** Endpoint Transfer Type.
+ * May be Bulk, Interrupt, Control or Isochronous
+ */
+ uint8_t ep_type;
+ uint8_t ep_stalled; /** Endpoint stall flag */
+};
+
+/* Driver state */
+struct dwc2_udc {
+ volatile uint32_t read_len;
+ struct dwc2_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
+ struct dwc2_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
+} g_dwc2_udc;
+
+static int usb_dwc2_reset(void)
+{
+ uint32_t count = 0U;
+
+ /* Wait for AHB master IDLE state. */
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+
+ /* Core Soft Reset */
+ count = 0U;
+ USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
+
+ return 0;
+}
+
+static inline int usb_dwc2_core_init(void)
+{
+ int ret;
+#if defined(CONFIG_USB_HS)
+
+#else
+ /* Select FS Embedded PHY */
+ USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
+#endif
+ /* Reset after a PHY select */
+ ret = usb_dwc2_reset();
+
+ /* Activate the USB Transceiver */
+ USB_OTG_GLB->GCCFG |= USB_OTG_GCCFG_PWRDWN;
+
+ return ret;
+}
+
+static void usb_dwc2_set_mode(uint8_t mode)
+{
+ USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
+
+ if (mode == USB_OTG_MODE_HOST) {
+ USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
+ } else if (mode == USB_OTG_MODE_DEVICE) {
+ USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
+ }
+}
+
+static void usb_dwc2_set_turnaroundtime(uint32_t hclk, uint8_t speed)
+{
+ uint32_t UsbTrd;
+
+ /* The USBTRD is configured according to the tables below, depending on AHB frequency
+ used by application. In the low AHB frequency range it is used to stretch enough the USB response
+ time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
+ latency to the Data FIFO */
+ if (speed == USB_OTG_SPEED_FULL) {
+ if ((hclk >= 14200000U) && (hclk < 15000000U)) {
+ /* hclk Clock Range between 14.2-15 MHz */
+ UsbTrd = 0xFU;
+ } else if ((hclk >= 15000000U) && (hclk < 16000000U)) {
+ /* hclk Clock Range between 15-16 MHz */
+ UsbTrd = 0xEU;
+ } else if ((hclk >= 16000000U) && (hclk < 17200000U)) {
+ /* hclk Clock Range between 16-17.2 MHz */
+ UsbTrd = 0xDU;
+ } else if ((hclk >= 17200000U) && (hclk < 18500000U)) {
+ /* hclk Clock Range between 17.2-18.5 MHz */
+ UsbTrd = 0xCU;
+ } else if ((hclk >= 18500000U) && (hclk < 20000000U)) {
+ /* hclk Clock Range between 18.5-20 MHz */
+ UsbTrd = 0xBU;
+ } else if ((hclk >= 20000000U) && (hclk < 21800000U)) {
+ /* hclk Clock Range between 20-21.8 MHz */
+ UsbTrd = 0xAU;
+ } else if ((hclk >= 21800000U) && (hclk < 24000000U)) {
+ /* hclk Clock Range between 21.8-24 MHz */
+ UsbTrd = 0x9U;
+ } else if ((hclk >= 24000000U) && (hclk < 27700000U)) {
+ /* hclk Clock Range between 24-27.7 MHz */
+ UsbTrd = 0x8U;
+ } else if ((hclk >= 27700000U) && (hclk < 32000000U)) {
+ /* hclk Clock Range between 27.7-32 MHz */
+ UsbTrd = 0x7U;
+ } else /* if(hclk >= 32000000) */
+ {
+ /* hclk Clock Range between 32-200 MHz */
+ UsbTrd = 0x6U;
+ }
+ } else if (speed == USB_OTG_SPEED_HIGH) {
+ UsbTrd = USBD_HS_TRDT_VALUE;
+ } else {
+ UsbTrd = USBD_DEFAULT_TRDT_VALUE;
+ }
+
+ USB_OTG_GLB->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
+ USB_OTG_GLB->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
+}
+
+static int usb_dwc2_flush_rxfifo(void)
+{
+ uint32_t count = 0;
+
+ USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
+
+ return 0;
+}
+
+static int usb_dwc2_flush_txfifo(uint32_t num)
+{
+ uint32_t count = 0U;
+
+ USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
+
+ return 0;
+}
+
+static void usb_set_txfifo(uint8_t fifo, uint16_t size)
+{
+ uint8_t i;
+ uint32_t Tx_Offset;
+
+ /* TXn min size = 16 words. (n : Transmit FIFO index)
+ When a TxFIFO is not used, the Configuration should be as follows:
+ case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
+ --> Txm can use the space allocated for Txn.
+ case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
+ --> Txn should be configured with the minimum space of 16 words
+ The FIFO is used optimally when used TxFIFOs are allocated in the top
+ of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+ When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
+
+ Tx_Offset = USB_OTG_GLB->GRXFSIZ;
+
+ if (fifo == 0U) {
+ USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset;
+ } else {
+ Tx_Offset += (USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ) >> 16;
+ for (i = 0U; i < (fifo - 1U); i++) {
+ Tx_Offset += (USB_OTG_GLB->DIEPTXF[i] >> 16);
+ }
+
+ /* Multiply Tx_Size by 2 to get higher performance */
+ USB_OTG_GLB->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset;
+ }
+}
+
+static uint8_t usb_dwc2_get_devspeed(void)
+{
+ uint8_t speed;
+ uint32_t DevEnumSpeed = USB_OTG_DEV->DSTS & USB_OTG_DSTS_ENUMSPD;
+
+ if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) {
+ speed = USB_OTG_SPEED_HIGH;
+ } else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
+ (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ)) {
+ speed = USB_OTG_SPEED_FULL;
+ } else {
+ speed = 0xFU;
+ }
+
+ return speed;
+}
+
+/**
+ * @brief USB_ReadInterrupts: return the global USB interrupt status
+ * @retval status
+ */
+static inline uint32_t usb_dwc2_get_glb_intstatus(void)
+{
+ uint32_t tmpreg;
+
+ tmpreg = USB_OTG_GLB->GINTSTS;
+ tmpreg &= USB_OTG_GLB->GINTMSK;
+
+ return tmpreg;
+}
+
+/**
+ * @brief usb_dwc2_get_outeps_intstatus: return the USB device OUT endpoints interrupt status
+ * @retval status
+ */
+static inline uint32_t usb_dwc2_get_outeps_intstatus(void)
+{
+ uint32_t tmpreg;
+
+ tmpreg = USB_OTG_DEV->DAINT;
+ tmpreg &= USB_OTG_DEV->DAINTMSK;
+
+ return ((tmpreg & 0xffff0000U) >> 16);
+}
+
+/**
+ * @brief usb_dwc2_get_ineps_intstatus: return the USB device IN endpoints interrupt status
+ * @retval status
+ */
+static inline uint32_t usb_dwc2_get_ineps_intstatus(void)
+{
+ uint32_t tmpreg;
+
+ tmpreg = USB_OTG_DEV->DAINT;
+ tmpreg &= USB_OTG_DEV->DAINTMSK;
+
+ return ((tmpreg & 0xFFFFU));
+}
+
+/**
+ * @brief Returns Device OUT EP Interrupt register
+ * @param epnum endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device OUT EP Interrupt register
+ */
+static inline uint32_t usb_dwc2_get_outep_intstatus(uint8_t epnum)
+{
+ uint32_t tmpreg;
+
+ tmpreg = USB_OTG_OUTEP((uint32_t)epnum)->DOEPINT;
+ tmpreg &= USB_OTG_DEV->DOEPMSK;
+
+ return tmpreg;
+}
+
+/**
+ * @brief Returns Device IN EP Interrupt register
+ * @param epnum endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device IN EP Interrupt register
+ */
+static inline uint32_t usb_dwc2_get_inep_intstatus(uint8_t epnum)
+{
+ uint32_t tmpreg, msk, emp;
+
+ msk = USB_OTG_DEV->DIEPMSK;
+ emp = USB_OTG_DEV->DIEPEMPMSK;
+ msk |= ((emp >> (epnum & 0x07)) & 0x1U) << 7;
+ tmpreg = USB_OTG_INEP((uint32_t)epnum)->DIEPINT & msk;
+
+ return tmpreg;
+}
+
+__WEAK void usb_dc_low_level_init(void)
+{
+}
+
+__WEAK void usb_dc_low_level_deinit(void)
+{
+}
+
+int usb_dc_init(void)
+{
+ int ret;
+
+ memset(&g_dwc2_udc, 0, sizeof(struct dwc2_udc));
+
+ usb_dc_low_level_init();
+
+ USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS;
+
+ USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
+
+ /* Disable DMA mode for FS instance */
+ if ((USB_OTG_GLB->CID & (0x1U << 8)) != 0U) {
+ // USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
+ // USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
+ }
+
+ ret = usb_dwc2_core_init();
+
+ /* Force Device Mode*/
+ usb_dwc2_set_mode(USB_OTG_MODE_DEVICE);
+
+ for (uint8_t i = 0U; i < 15U; i++) {
+ USB_OTG_GLB->DIEPTXF[i] = 0U;
+ }
+
+#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) || \
+ defined(STM32F7) || defined(STM32H7)
+#ifdef CONFIG_DWC2_VBUS_SENSING_ENABLE
+ /* Enable HW VBUS sensing */
+ USB_OTG_GLB->GCCFG |= USB_OTG_GCCFG_VBDEN;
+#else
+ /* Deactivate VBUS Sensing B */
+ USB_OTG_GLB->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
+
+ /* B-peripheral session valid override enable */
+ USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
+ USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
+#endif
+
+#else
+#ifdef CONFIG_DWC2_VBUS_SENSING_ENABLE
+ /* Enable HW VBUS sensing */
+ USB_OTG_GLB->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS;
+ USB_OTG_GLB->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
+#else
+ /*
+ * Disable HW VBUS sensing. VBUS is internally considered to be always
+ * at VBUS-Valid level (5V).
+ */
+ USB_OTG_GLB->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
+ USB_OTG_GLB->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
+ USB_OTG_GLB->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
+#endif
+
+#endif
+ /* Restart the Phy Clock */
+ USB_OTG_PCGCCTL = 0U;
+
+ /* Device mode configuration */
+ USB_OTG_DEV->DCFG |= DCFG_FRAME_INTERVAL_80;
+
+#if defined(CONFIG_USB_HS)
+ /* Set Core speed to High speed mode */
+ USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH;
+#else
+ USB_OTG_DEV->DCFG |= USB_OTG_SPEED_FULL;
+#endif
+
+ ret = usb_dwc2_flush_txfifo(0x10U);
+ ret = usb_dwc2_flush_rxfifo();
+
+ for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
+ if ((USB_OTG_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) {
+ if (i == 0U) {
+ USB_OTG_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
+ } else {
+ USB_OTG_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
+ }
+ } else {
+ USB_OTG_INEP(i)->DIEPCTL = 0U;
+ }
+
+ USB_OTG_INEP(i)->DIEPTSIZ = 0U;
+ USB_OTG_INEP(i)->DIEPINT = 0xFB7FU;
+ }
+ for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
+ if ((USB_OTG_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) {
+ if (i == 0U) {
+ USB_OTG_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
+ } else {
+ USB_OTG_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
+ }
+ } else {
+ USB_OTG_OUTEP(i)->DOEPCTL = 0U;
+ }
+
+ USB_OTG_OUTEP(i)->DOEPTSIZ = 0U;
+ USB_OTG_OUTEP(i)->DOEPINT = 0xFB7FU;
+ }
+
+ /* Clear all pending Device Interrupts */
+ USB_OTG_DEV->DIEPMSK = 0U;
+ USB_OTG_DEV->DOEPMSK = 0U;
+ USB_OTG_DEV->DAINTMSK = 0U;
+
+ /* Disable all interrupts. */
+ USB_OTG_GLB->GINTMSK = 0U;
+ /* Clear any pending interrupts */
+ USB_OTG_GLB->GINTSTS = 0xBFFFFFFFU;
+
+ /* Enable interrupts matching to the Device mode ONLY */
+ USB_OTG_GLB->GINTMSK = USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM |
+ USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_RXFLVLM |
+ USB_OTG_GINTMSK_WUIM;
+
+#if CONFIG_DWC2_VBUS_SENSING
+ USB_OTG_GLB->GINTMSK |= (USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_SRQIM);
+#endif
+#if 0
+ USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_SOFM;
+#endif
+ USB_OTG_DEV->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM;
+ USB_OTG_DEV->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
+
+ USB_OTG_GLB->GRXFSIZ = (CONFIG_USB_DWC2_RX_FIFO_SIZE / 4);
+
+ usb_set_txfifo(0, CONFIG_USB_DWC2_TX0_FIFO_SIZE / 4);
+ usb_set_txfifo(1, CONFIG_USB_DWC2_TX1_FIFO_SIZE / 4);
+ usb_set_txfifo(2, CONFIG_USB_DWC2_TX2_FIFO_SIZE / 4);
+ usb_set_txfifo(3, CONFIG_USB_DWC2_TX3_FIFO_SIZE / 4);
+#if USB_NUM_BIDIR_ENDPOINTS > 4
+ usb_set_txfifo(4, CONFIG_USB_DWC2_TX4_FIFO_SIZE / 4);
+#endif
+#if USB_NUM_BIDIR_ENDPOINTS > 5
+ usb_set_txfifo(5, CONFIG_USB_DWC2_TX5_FIFO_SIZE / 4);
+#endif
+ USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
+ USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_SDIS;
+
+ return ret;
+}
+
+int usb_dc_deinit(void)
+{
+ usb_dc_low_level_deinit();
+ /* Clear Pending interrupt */
+ for (uint8_t i = 0U; i < 15U; i++) {
+ USB_OTG_INEP(i)->DIEPINT = 0xFB7FU;
+ USB_OTG_OUTEP(i)->DOEPINT = 0xFB7FU;
+ }
+
+ /* Clear interrupt masks */
+ USB_OTG_DEV->DIEPMSK = 0U;
+ USB_OTG_DEV->DOEPMSK = 0U;
+ USB_OTG_DEV->DAINTMSK = 0U;
+
+ /* Flush the FIFO */
+ usb_dwc2_flush_txfifo(0x10U);
+ usb_dwc2_flush_rxfifo();
+
+ USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS;
+
+ return 0;
+}
+
+int usbd_set_address(const uint8_t addr)
+{
+ USB_OTG_DEV->DCFG &= ~(USB_OTG_DCFG_DAD);
+ USB_OTG_DEV->DCFG |= ((uint32_t)addr << 4) & USB_OTG_DCFG_DAD;
+ return 0;
+}
+
+int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
+ uint8_t ep_mps;
+
+ if (!ep_cfg) {
+ return -1;
+ }
+
+ if (USB_EP_DIR_IS_OUT(ep_cfg->ep_addr)) {
+ g_dwc2_udc.out_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
+ g_dwc2_udc.out_ep[ep_idx].ep_type = ep_cfg->ep_type;
+
+ USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx));
+
+ ep_mps = ep_cfg->ep_mps;
+ if (ep_idx == 0) {
+ switch (ep_cfg->ep_mps) {
+ case 8:
+ ep_mps = EP_MPS_8;
+ break;
+ case 16:
+ ep_mps = EP_MPS_16;
+ break;
+ case 32:
+ ep_mps = EP_MPS_32;
+ break;
+ case 64:
+ ep_mps = EP_MPS_64;
+ break;
+ }
+ }
+ USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (ep_mps & USB_OTG_DOEPCTL_MPSIZ) |
+ ((uint32_t)ep_cfg->ep_type << 18) |
+ USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
+ USB_OTG_DOEPCTL_USBAEP;
+ /* EP enable */
+ USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+ } else {
+ g_dwc2_udc.in_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
+ g_dwc2_udc.in_ep[ep_idx].ep_type = ep_cfg->ep_type;
+
+ USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx);
+
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= (ep_cfg->ep_mps & USB_OTG_DIEPCTL_MPSIZ) |
+ ((uint32_t)ep_cfg->ep_type << 18) | (ep_idx << 22) |
+ USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
+ USB_OTG_DIEPCTL_USBAEP;
+ }
+ return 0;
+}
+
+int usbd_ep_close(const uint8_t ep)
+{
+ return 0;
+}
+
+int usbd_ep_set_stall(const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ if (((USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (ep_idx != 0U)) {
+ USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
+ }
+ USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
+ } else {
+ if (((USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (ep_idx != 0U)) {
+ USB_OTG_INEP(ep_idx)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
+ }
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
+ }
+
+ return 0;
+}
+
+int usbd_ep_clear_stall(const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
+ if ((g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
+ (g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
+ USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
+ }
+ } else {
+ USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
+ if ((g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
+ (g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
+ }
+ }
+ return 0;
+}
+
+int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
+{
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ } else {
+ }
+ return 0;
+}
+
+int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *ret_bytes)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint32_t len32b;
+ uint32_t pktcnt;
+
+ if (!data && data_len) {
+ return -1;
+ }
+
+ if (data_len > g_dwc2_udc.in_ep[ep_idx].ep_mps) {
+ data_len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
+ }
+
+ len32b = (data_len + 3U) / 4U;
+
+ while (((USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) ||
+ (USB_OTG_INEP(ep_idx)->DTXFSTS < len32b)) {
+ }
+
+ if (!data_len) {
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
+ /* EP enable, IN data in FIFO */
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
+
+ return 0;
+ }
+
+ /* Program the transfer size and packet count
+ * as follows: xfersize = N * maxpacket +
+ * short_packet pktcnt = N + (short_packet
+ * exist ? 1 : 0)
+ */
+ pktcnt = (uint16_t)((data_len + g_dwc2_udc.in_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc.in_ep[ep_idx].ep_mps);
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19));
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len);
+ /* EP enable, IN data in FIFO */
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
+
+ if (g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
+ USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
+
+ if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
+ } else {
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
+ }
+ }
+
+ for (uint8_t i = 0U; i < len32b; i++) {
+ USB_OTG_FIFO(ep_idx) = ((uint32_t *)data)[i];
+ }
+
+ if (ret_bytes) {
+ *ret_bytes = data_len;
+ }
+
+ return 0;
+}
+
+int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint32_t *pdest = (uint32_t *)data;
+ uint32_t len32b;
+ uint32_t read_count;
+ uint32_t pktcnt;
+
+ if (!data && max_data_len) {
+ return -1;
+ }
+
+ if (((uint32_t)data) & 0x03) {
+ return -2;
+ }
+
+ if (max_data_len > g_dwc2_udc.out_ep[ep_idx].ep_mps) {
+ max_data_len = g_dwc2_udc.out_ep[ep_idx].ep_mps;
+ }
+
+ if (!max_data_len) {
+ if (ep_idx != 0) {
+ /* Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ pktcnt = (uint16_t)((max_data_len + g_dwc2_udc.out_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc.out_ep[ep_idx].ep_mps);
+ USB_OTG_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
+ USB_OTG_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
+ USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
+ USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & g_dwc2_udc.out_ep[ep_idx].ep_mps * pktcnt);
+ /* EP enable */
+ USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+ }
+
+ return 0;
+ }
+
+ read_count = g_dwc2_udc.read_len;
+
+ read_count = MIN(read_count, max_data_len);
+
+ len32b = ((uint32_t)read_count + 3U) / 4U;
+
+ for (uint8_t i = 0U; i < len32b; i++) {
+ *pdest = USB_OTG_FIFO(0U);
+ pdest++;
+ }
+
+ if (read_bytes) {
+ *read_bytes = read_count;
+ }
+
+ g_dwc2_udc.read_len = 0;
+ return 0;
+}
+
+void USBD_IRQHandler(void)
+{
+ uint32_t gint_status, temp, epnum, ep_intr, epint;
+ gint_status = usb_dwc2_get_glb_intstatus();
+
+ if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_DEVICE) {
+ /* Avoid spurious interrupt */
+ if (gint_status == 0) {
+ return;
+ }
+
+ /* Handle RxQLevel Interrupt */
+ if (gint_status & USB_OTG_GINTSTS_RXFLVL) {
+ USB_MASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
+
+ temp = USB_OTG_GLB->GRXSTSP;
+ epnum = temp & USB_OTG_GRXSTSP_EPNUM;
+ g_dwc2_udc.read_len = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
+
+ if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) {
+ if (g_dwc2_udc.read_len != 0U) {
+ if (epnum == 0) {
+ usbd_event_notify_handler(USBD_EVENT_EP0_OUT_NOTIFY, NULL);
+ } else {
+ usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(epnum | USB_EP_DIR_OUT));
+ }
+ }
+ } else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_SETUP_UPDT) {
+ usbd_event_notify_handler(USBD_EVENT_SETUP_NOTIFY, NULL);
+ } else {
+ /* ... */
+ }
+ USB_UNMASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
+ }
+
+ if (gint_status & USB_OTG_GINTSTS_OEPINT) {
+ epnum = 0;
+ ep_intr = usb_dwc2_get_outeps_intstatus();
+ while (ep_intr != 0U) {
+ if ((ep_intr & 0x1U) != 0U) {
+ epint = usb_dwc2_get_outep_intstatus(epnum);
+ USB_OTG_OUTEP(epnum)->DOEPINT = epint;
+
+ if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) {
+ USB_OTG_OUTEP(0)->DOEPTSIZ = 1U << USB_OTG_DOEPTSIZ_PKTCNT_Pos |
+ (USB_OTG_OUTEP(0)->DOEPCTL & USB_OTG_DOEPCTL_MPSIZ) << USB_OTG_DOEPTSIZ_XFRSIZ_Pos;
+ USB_OTG_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
+ }
+ if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) {
+ if (epnum == 0) {
+ USB_OTG_OUTEP(0)->DOEPTSIZ = 1U << USB_OTG_DOEPTSIZ_PKTCNT_Pos |
+ (USB_OTG_OUTEP(0)->DOEPCTL & USB_OTG_DOEPCTL_MPSIZ) << USB_OTG_DOEPTSIZ_XFRSIZ_Pos;
+ USB_OTG_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
+ }
+ }
+ }
+ ep_intr >>= 1U;
+ epnum++;
+ }
+ }
+ if (gint_status & USB_OTG_GINTSTS_IEPINT) {
+ epnum = 0U;
+ ep_intr = usb_dwc2_get_ineps_intstatus();
+ while (ep_intr != 0U) {
+ if ((ep_intr & 0x1U) != 0U) {
+ epint = usb_dwc2_get_inep_intstatus(epnum);
+ USB_OTG_INEP(epnum)->DIEPINT = epint;
+
+ if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) {
+ if (epnum == 0) {
+ usbd_event_notify_handler(USBD_EVENT_EP0_IN_NOTIFY, NULL);
+ } else {
+ usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(epnum | USB_EP_DIR_IN));
+ }
+ }
+ }
+ ep_intr >>= 1U;
+ epnum++;
+ }
+ }
+ if (gint_status & USB_OTG_GINTSTS_USBRST) {
+ USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBRST;
+ USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_RWUSIG;
+
+ usb_dwc2_flush_txfifo(0x10U);
+ usb_dwc2_flush_rxfifo();
+ for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
+ USB_OTG_INEP(i)->DIEPINT = 0xFB7FU;
+ USB_OTG_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
+ USB_OTG_INEP(i)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
+ USB_OTG_OUTEP(i)->DOEPINT = 0xFB7FU;
+ USB_OTG_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
+ USB_OTG_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
+ }
+ USB_OTG_DEV->DAINTMSK |= 0x10001U;
+
+ USB_OTG_OUTEP(0U)->DOEPTSIZ = 0U;
+ USB_OTG_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
+ USB_OTG_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
+ USB_OTG_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
+ USB_OTG_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
+
+ usbd_event_notify_handler(USBD_EVENT_RESET, NULL);
+ }
+ if (gint_status & USB_OTG_GINTSTS_ENUMDNE) {
+ USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_ENUMDNE;
+ usb_dwc2_set_turnaroundtime(SystemCoreClock, usb_dwc2_get_devspeed());
+ USB_OTG_DEV->DCTL |= USB_OTG_DCTL_CGINAK;
+ }
+ if (gint_status & USB_OTG_GINTSTS_SOF) {
+ USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_SOF;
+ }
+ if (gint_status & USB_OTG_GINTSTS_USBSUSP) {
+ USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBSUSP;
+ }
+ if (gint_status & USB_OTG_GINTSTS_OTGINT) {
+ temp = USB_OTG_GLB->GOTGINT;
+ if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) {
+ } else {
+ }
+ USB_OTG_GLB->GOTGINT |= temp;
+ }
+ }
+}
diff --git a/port/synopsys/usb_synopsys_reg.h b/port/dwc2/usb_dwc2_reg.h
index d3acceb9..ec137b20 100644
--- a/port/synopsys/usb_synopsys_reg.h
+++ b/port/dwc2/usb_dwc2_reg.h
@@ -1578,18 +1578,6 @@ typedef struct
* @}
*/
-/** @defgroup USB_LL Device Speed
- * @{
- */
-#define USBD_HS_SPEED 0U
-#define USBD_HSINFS_SPEED 1U
-#define USBH_HS_SPEED 0U
-#define USBD_FS_SPEED 2U
-#define USBH_FSLS_SPEED 1U
-/**
- * @}
- */
-
/** @defgroup USB_LL_Core_Speed USB Low Layer Core Speed
* @{
*/
@@ -1623,16 +1611,6 @@ typedef struct
* @}
*/
-/** @defgroup USB_LL_Core_MPS USB Low Layer Core MPS
- * @{
- */
-#define USB_OTG_HS_MAX_PACKET_SIZE 512U
-#define USB_OTG_FS_MAX_PACKET_SIZE 64U
-#define USB_OTG_MAX_EP0_SIZE 64U
-/**
- * @}
- */
-
/** @defgroup USB_LL_Core_PHY_Frequency USB Low Layer Core PHY Frequency
* @{
*/
@@ -1665,24 +1643,6 @@ typedef struct
* @}
*/
-/** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed
- * @{
- */
-#define EP_SPEED_LOW 0U
-#define EP_SPEED_FULL 1U
-#define EP_SPEED_HIGH 2U
-/**
- * @}
- */
-
-/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
- * @{
- */
-#define EP_TYPE_CTRL 0U
-#define EP_TYPE_ISOC 1U
-#define EP_TYPE_BULK 2U
-#define EP_TYPE_INTR 3U
-#define EP_TYPE_MSK 3U
/**
* @}
*/
@@ -1734,187 +1694,11 @@ typedef struct
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U
#define GRXSTS_PKTSTS_CH_HALTED 7U
-#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_PCGCCTL_BASE)
-#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_HOST_PORT_BASE)
-
-#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)(USBx_BASE + USB_OTG_DEVICE_BASE))
-#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)(USBx_BASE + USB_OTG_IN_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
-#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)(USBx_BASE + USB_OTG_OUT_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
-#define USBx_DFIFO(i) *(__IO uint32_t *)(USBx_BASE + USB_OTG_FIFO_BASE + ((i) * USB_OTG_FIFO_SIZE))
-
-#define USBx_HOST ((USB_OTG_HostTypeDef *)(USBx_BASE + USB_OTG_HOST_BASE))
-#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)(USBx_BASE + USB_OTG_HOST_CHANNEL_BASE + ((i) * USB_OTG_HOST_CHANNEL_SIZE)))
-
-#define EP_ADDR_MSK 0xFU
-
#define USB_MASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK &= ~(__INTERRUPT__))
#define USB_UNMASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK |= (__INTERRUPT__))
-
+#define USB_MASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_CHHM)
+#define USB_UNMASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM)
#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__))
#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__))
-
-
-typedef enum
-{
- USB_DEVICE_MODE = 0,
- USB_HOST_MODE = 1,
- USB_DRD_MODE = 2
-} USB_OTG_ModeTypeDef;
-
-/**
- * @brief URB States definition
- */
-typedef enum
-{
- URB_IDLE = 0,
- URB_DONE,
- URB_NOTREADY,
- URB_NYET,
- URB_ERROR,
- URB_STALL
-} USB_OTG_URBStateTypeDef;
-
-/**
- * @brief Host channel States definition
- */
-typedef enum
-{
- HC_IDLE = 0,
- HC_XFRC,
- HC_HALTED,
- HC_NAK,
- HC_NYET,
- HC_STALL,
- HC_XACTERR,
- HC_BBLERR,
- HC_DATATGLERR
-} USB_OTG_HCStateTypeDef;
-
-/**
- * @brief USB Instance Initialization Structure definition
- */
-typedef struct
-{
- uint32_t dev_endpoints; /*!< Device Endpoints number.
- This parameter depends on the used USB core.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint32_t Host_channels; /*!< Host Channels number.
- This parameter Depends on the used USB core.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint32_t speed; /*!< USB Core speed.
- This parameter can be any value of @ref USB_Core_Speed */
-
- uint32_t dma_enable; /*!< Enable or disable of the USB embedded DMA used only for OTG HS. */
-
- uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */
-
- uint32_t phy_itface; /*!< Select the used PHY interface.
- This parameter can be any value of @ref USB_Core_PHY */
-
- uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
-
- uint32_t low_power_enable; /*!< Enable or disable the low power mode. */
-
- uint32_t lpm_enable; /*!< Enable or disable Link Power Management. */
-
- uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */
-
- uint32_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */
-
- uint32_t use_dedicated_ep1; /*!< Enable or disable the use of the dedicated EP1 interrupt. */
-
- uint32_t use_external_vbus; /*!< Enable or disable the use of the external VBUS. */
-
-} USB_OTG_CfgTypeDef;
-
-typedef struct
-{
- uint8_t num; /*!< Endpoint number
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint8_t is_in; /*!< Endpoint direction
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t is_stall; /*!< Endpoint stall condition
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t type; /*!< Endpoint type
- This parameter can be any value of @ref USB_EP_Type_ */
-
- uint8_t data_pid_start; /*!< Initial data PID
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t even_odd_frame; /*!< IFrame parity
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint16_t tx_fifo_num; /*!< Transmission FIFO number
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint32_t maxpacket; /*!< Endpoint Max packet size
- This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
-
- uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
-
- uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */
-
- uint32_t xfer_len; /*!< Current transfer length */
-
- uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
-} USB_OTG_EPTypeDef;
-
-typedef struct
-{
- uint8_t dev_addr; /*!< USB device address.
- This parameter must be a number between Min_Data = 1 and Max_Data = 255 */
-
- uint8_t ch_num; /*!< Host channel number.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint8_t ep_num; /*!< Endpoint number.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint8_t ep_is_in; /*!< Endpoint direction
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t speed; /*!< USB Host speed.
- This parameter can be any value of @ref USB_Core_Speed_ */
-
- uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */
-
- uint8_t process_ping; /*!< Execute the PING protocol for HS mode. */
-
- uint8_t ep_type; /*!< Endpoint Type.
- This parameter can be any value of @ref USB_EP_Type_ */
-
- uint16_t max_packet; /*!< Endpoint Max packet size.
- This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
-
- uint8_t data_pid; /*!< Initial data PID.
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */
-
- uint32_t xfer_len; /*!< Current transfer length. */
-
- uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */
-
- uint8_t toggle_in; /*!< IN transfer current toggle flag.
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t toggle_out; /*!< OUT transfer current toggle flag
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */
-
- uint32_t ErrCnt; /*!< Host channel error count. */
-
- USB_OTG_URBStateTypeDef urb_state; /*!< URB state.
- This parameter can be any value of @ref USB_OTG_URBStateTypeDef */
-
- USB_OTG_HCStateTypeDef state; /*!< Host Channel state.
- This parameter can be any value of @ref USB_OTG_HCStateTypeDef */
-} USB_OTG_HCTypeDef;
-
-#endif \ No newline at end of file
+#define CLEAR_HC_INT(chnum, __INTERRUPT__) (USBx_HC(chnum)->HCINT = (__INTERRUPT__))
+#endif
diff --git a/port/dwc2/usb_hc_dwc2.c b/port/dwc2/usb_hc_dwc2.c
new file mode 100644
index 00000000..d8bf8a7d
--- /dev/null
+++ b/port/dwc2/usb_hc_dwc2.c
@@ -0,0 +1,1389 @@
+#include "usbh_core.h"
+#include "usb_dwc2_reg.h"
+
+#ifndef USBH_IRQHandler
+#define USBH_IRQHandler OTG_HS_IRQHandler
+#endif
+
+#ifndef USB_BASE
+#define USB_BASE (0x40040000UL)
+#endif
+
+#ifndef CONFIG_USB_DWC2_CHANNELS
+#define CONFIG_USB_DWC2_CHANNELS 12 /* Number of host channels */
+#endif
+
+#define USB_OTG_GLB ((USB_OTG_GlobalTypeDef *)(USB_BASE))
+#define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)USB_BASE + USB_OTG_PCGCCTL_BASE)
+#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USB_BASE + USB_OTG_HOST_PORT_BASE)
+#define USBx_HOST ((USB_OTG_HostTypeDef *)(USB_BASE + USB_OTG_HOST_BASE))
+#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)(USB_BASE + USB_OTG_HOST_CHANNEL_BASE + ((i)*USB_OTG_HOST_CHANNEL_SIZE)))
+#define USB_OTG_FIFO(i) *(__IO uint32_t *)(USB_BASE + USB_OTG_FIFO_BASE + ((i)*USB_OTG_FIFO_SIZE))
+
+/* This structure retains the state of one host channel. NOTE: Since there
+ * is only one channel operation active at a time, some of the fields in
+ * in the structure could be moved in struct stm32_ubhost_s to achieve
+ * some memory savings.
+ */
+
+struct dwc2_pipe {
+ uint8_t ep_addr;
+ uint8_t ep_type;
+ uint16_t ep_mps;
+ uint8_t speed;
+ uint8_t dev_addr;
+ uint8_t data_pid;
+ bool inuse; /* True: This channel is "in use" */
+ uint8_t interval; /* Interrupt/isochronous EP polling interval */
+ uint32_t xferlen; /* for HCTSIZx*/
+ uint8_t num_packets; /* for HCTSIZx*/
+ volatile int result; /* The result of the transfer */
+ volatile uint32_t xfrd; /* Bytes transferred (at end of transfer) */
+ volatile bool waiter; /* True: Thread is waiting for a channel event */
+ usb_osal_sem_t waitsem; /* Channel wait semaphore */
+ usb_osal_mutex_t exclsem; /* Support mutually exclusive access */
+#ifdef CONFIG_USBHOST_ASYNCH
+ usbh_asynch_callback_t callback; /* Transfer complete callback */
+ void *arg; /* Argument that accompanies the callback */
+#endif
+};
+
+/* A channel represents on uni-directional endpoint. So, in the case of the
+ * bi-directional, control endpoint, there must be two channels to represent
+ * the endpoint.
+ */
+
+struct usb_dwc2_ctrlinfo {
+ uint8_t inndx; /* EP0 IN control channel index */
+ uint8_t outndx; /* EP0 OUT control channel index */
+};
+
+struct dwc2_hcd {
+ volatile bool connected;
+ struct usb_work work;
+ struct dwc2_pipe chan[CONFIG_USB_DWC2_CHANNELS];
+} g_dwc2_hcd;
+
+static int usb_dwc2_reset(void)
+{
+ uint32_t count = 0U;
+
+ /* Wait for AHB master IDLE state. */
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+
+ /* Core Soft Reset */
+ count = 0U;
+ USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
+
+ return 0;
+}
+
+static inline int usb_dwc2_core_init(void)
+{
+ int ret;
+#if defined(CONFIG_USB_DWC2_ULPI_PHY)
+
+#else
+ /* Select FS Embedded PHY */
+ USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
+#endif
+ /* Reset after a PHY select */
+ ret = usb_dwc2_reset();
+
+ /* Activate the USB Transceiver */
+ USB_OTG_GLB->GCCFG |= USB_OTG_GCCFG_PWRDWN;
+
+ return ret;
+}
+
+static void usb_dwc2_set_mode(uint8_t mode)
+{
+ USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
+
+ if (mode == USB_OTG_MODE_HOST) {
+ USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
+ } else if (mode == USB_OTG_MODE_DEVICE) {
+ USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
+ }
+}
+
+static int usb_dwc2_flush_rxfifo(void)
+{
+ uint32_t count = 0;
+
+ USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
+
+ return 0;
+}
+
+static int usb_dwc2_flush_txfifo(uint32_t num)
+{
+ uint32_t count = 0U;
+
+ USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
+
+ return 0;
+}
+
+static void usb_dwc2_drivebus(uint8_t state)
+{
+ __IO uint32_t hprt0 = 0U;
+
+ hprt0 = USBx_HPRT0;
+
+ hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
+
+ if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U)) {
+ USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
+ }
+ if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U)) {
+ USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
+ }
+}
+
+/**
+ * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
+ * HCFG register on the PHY type and set the right frame interval
+ * @param USBx Selected device
+ * @param freq clock frequency
+ * This parameter can be one of these values:
+ * HCFG_48_MHZ : Full Speed 48 MHz Clock
+ * HCFG_6_MHZ : Low Speed 6 MHz Clock
+ * @retval HAL status
+ */
+static void usb_dwc2_init_fsls_pclksel(uint8_t freq)
+{
+ USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
+ USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
+
+ if (freq == HCFG_48_MHZ) {
+ USBx_HOST->HFIR = 48000U;
+ } else if (freq == HCFG_6_MHZ) {
+ USBx_HOST->HFIR = 6000U;
+ } else {
+ /* ... */
+ }
+}
+
+static void dwc2_pipe_init(uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint8_t ep_mps, uint8_t speed)
+{
+ uint32_t regval;
+
+ /* Clear old interrupt conditions for this host channel. */
+ USBx_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
+
+ /* Enable channel interrupts required for this transfer. */
+ regval = USB_OTG_HCINTMSK_XFRCM |
+ USB_OTG_HCINTMSK_STALLM |
+ USB_OTG_HCINTMSK_TXERRM |
+ USB_OTG_HCINTMSK_DTERRM |
+ USB_OTG_HCINTMSK_AHBERR;
+
+ if ((ep_addr & 0x80U) == 0x80U) {
+ regval |= USB_OTG_HCINTMSK_BBERRM;
+ }
+
+ switch (ep_type) {
+ case USB_ENDPOINT_TYPE_CONTROL:
+ case USB_ENDPOINT_TYPE_BULK:
+ if ((ep_addr & 0x80U) == 0x00U) {
+ regval |= USB_OTG_HCINTMSK_NYET;
+ }
+ break;
+ case USB_ENDPOINT_TYPE_INTERRUPT:
+ regval |= USB_OTG_HCINTMSK_FRMORM | USB_OTG_HCINTMSK_NAKM;
+ break;
+ case USB_ENDPOINT_TYPE_ISOCHRONOUS:
+ regval |= USB_OTG_HCINTMSK_FRMORM;
+ break;
+ }
+
+ USBx_HC((uint32_t)ch_num)->HCINTMSK = regval;
+
+ /* Enable the top level host channel interrupt. */
+ USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
+
+ /* Make sure host channel interrupts are enabled. */
+ USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_HCIM;
+
+ /* Program the HCCHAR register */
+
+ regval = (((uint32_t)ep_mps << USB_OTG_HCCHAR_MPSIZ_Pos) & USB_OTG_HCCHAR_MPSIZ) |
+ ((((uint32_t)ep_addr & 0x7FU) << USB_OTG_HCCHAR_EPNUM_Pos) & USB_OTG_HCCHAR_EPNUM) |
+ (((uint32_t)ep_type << USB_OTG_HCCHAR_EPTYP_Pos) & USB_OTG_HCCHAR_EPTYP) |
+ (((uint32_t)devaddr << USB_OTG_HCCHAR_DAD_Pos) & USB_OTG_HCCHAR_DAD);
+
+ if ((ep_addr & 0x80U) == 0x80U) {
+ regval |= USB_OTG_HCCHAR_EPDIR;
+ }
+
+ /* LS device plugged to HUB */
+ if (speed == USB_SPEED_LOW) {
+ regval |= USB_OTG_HCCHAR_LSDEV;
+ }
+
+ if (ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
+ regval |= USB_OTG_HCCHAR_ODDFRM;
+ }
+
+ USBx_HC((uint32_t)ch_num)->HCCHAR = regval;
+}
+
+static uint8_t usb_dwc2_calculate_packet_num(uint32_t input_size, uint8_t ep_addr, uint16_t ep_mps, uint32_t *output_size)
+{
+ uint16_t num_packets;
+
+ num_packets = (uint16_t)((input_size + ep_mps - 1U) / ep_mps);
+
+ if (num_packets > 256) {
+ num_packets = 256;
+ }
+
+ if (input_size == 0) {
+ num_packets = 1;
+ }
+
+ if (ep_addr & 0x80) {
+ input_size = num_packets * ep_mps;
+ } else {
+ }
+
+ *output_size = input_size;
+ return num_packets;
+}
+/*
+* For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
+* max_packet size.
+*/
+static inline void usb_dwc2_pipe_transfer(uint8_t ch_num, uint8_t ep_addr, uint32_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
+{
+ __IO uint32_t tmpreg;
+ uint8_t is_oddframe;
+
+ /* Initialize the HCTSIZn register */
+ USBx_HC(ch_num)->HCTSIZ = (size & USB_OTG_HCTSIZ_XFRSIZ) |
+ (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
+ (((uint32_t)pid << 29) & USB_OTG_HCTSIZ_DPID);
+
+ /* xfer_buff MUST be 32-bits aligned */
+ USBx_HC(ch_num)->HCDMA = (uint32_t)buf;
+
+ is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
+ USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
+ USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
+
+ /* make sure to set the correct ep direction */
+ if (ep_addr & 0x80) {
+ tmpreg |= USB_OTG_HCCHAR_EPDIR;
+ } else {
+ tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
+ }
+
+ /* Set host channel enable */
+ tmpreg = USBx_HC(ch_num)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(ch_num)->HCCHAR = tmpreg;
+}
+
+static void usb_dwc2_halt(uint8_t ch_num)
+{
+ uint32_t count = 0U;
+ uint32_t HcEpType = (USBx_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
+ uint32_t ChannelEna = (USBx_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
+
+ if (((USB_OTG_GLB->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) &&
+ (ChannelEna == 0U)) {
+ return;
+ }
+
+ /* Check for space in the request queue to issue the halt. */
+ if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK)) {
+ USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
+
+ if ((USB_OTG_GLB->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U) {
+ if ((USB_OTG_GLB->HNPTXSTS & (0xFFU << 16)) == 0U) {
+ USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+ USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
+ do {
+ if (++count > 1000U) {
+ break;
+ }
+ } while ((USBx_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ } else {
+ USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ }
+ }
+ } else {
+ USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
+
+ if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U) {
+ USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+ USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
+ do {
+ if (++count > 1000U) {
+ break;
+ }
+ } while ((USBx_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ } else {
+ USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ }
+ }
+}
+/**
+ * @brief USB_ReadInterrupts: return the global USB interrupt status
+ * @retval status
+ */
+static inline uint32_t usb_dwc2_get_glb_intstatus(void)
+{
+ uint32_t tmpreg;
+
+ tmpreg = USB_OTG_GLB->GINTSTS;
+ tmpreg &= USB_OTG_GLB->GINTMSK;
+
+ return tmpreg;
+}
+
+/****************************************************************************
+ * Name: dwc2_pipe_alloc
+ *
+ * Description:
+ * Allocate a channel.
+ *
+ ****************************************************************************/
+
+static int dwc2_pipe_alloc(void)
+{
+ int chidx;
+
+ /* Search the table of channels */
+
+ for (chidx = 0; chidx < CONFIG_USB_DWC2_CHANNELS; chidx++) {
+ /* Is this channel available? */
+ if (!g_dwc2_hcd.chan[chidx].inuse) {
+ /* Yes... make it "in use" and return the index */
+
+ g_dwc2_hcd.chan[chidx].inuse = true;
+ return chidx;
+ }
+ }
+
+ /* All of the channels are "in-use" */
+
+ return -EBUSY;
+}
+
+/****************************************************************************
+ * Name: dwc2_pipe_free
+ *
+ * Description:
+ * Free a previoiusly allocated channel.
+ *
+ ****************************************************************************/
+
+static void dwc2_pipe_free(int chidx)
+{
+ /* Mark the channel available */
+
+ g_dwc2_hcd.chan[chidx].inuse = false;
+}
+
+/****************************************************************************
+ * Name: dwc2_pipe_freeall
+ *
+ * Description:
+ * Free all channels.
+ *
+ ****************************************************************************/
+
+static inline void dwc2_pipe_freeall(void)
+{
+ uint8_t chidx;
+
+ /* Free all host channels */
+
+ for (chidx = 1; chidx < CONFIG_USB_DWC2_CHANNELS; chidx++) {
+ dwc2_pipe_free(chidx);
+ }
+}
+
+/****************************************************************************
+ * Name: dwc2_pipe_waitsetup
+ *
+ * Description:
+ * Set the request for the transfer complete event well BEFORE enabling
+ * the transfer (as soon as we are absolutely committed to the transfer).
+ * We do this to minimize race conditions. This logic would have to be
+ * expanded if we want to have more than one packet in flight at a time!
+ *
+ * Assumptions:
+ * Called from a normal thread context BEFORE the transfer has been
+ * started.
+ *
+ ****************************************************************************/
+
+static int dwc2_pipe_waitsetup(struct dwc2_pipe *chan)
+{
+ size_t flags;
+ int ret = -ENODEV;
+
+ flags = usb_osal_enter_critical_section();
+
+ /* Is the device still connected? */
+
+ if (usbh_get_port_connect_status(1)) {
+ /* Yes.. then set waiter to indicate that we expect to be informed
+ * when either (1) the device is disconnected, or (2) the transfer
+ * completed.
+ */
+ chan->waiter = true;
+ chan->result = -EBUSY;
+ chan->xfrd = 0;
+#ifdef CONFIG_USBHOST_ASYNCH
+ chan->callback = NULL;
+ chan->arg = NULL;
+#endif
+ ret = 0;
+ }
+ usb_osal_leave_critical_section(flags);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: dwc2_pipe_asynchsetup
+ *
+ * Description:
+ * Set the request for the transfer complete event well BEFORE enabling
+ * the transfer (as soon as we are absolutely committed to the to avoid
+ * transfer). We do this to minimize race conditions. This logic would
+ * have to be expanded if we want to have more than one packet in flight
+ * at a time!
+ *
+ * Assumptions:
+ * Might be called from the level of an interrupt handler
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST_ASYNCH
+static int dwc2_pipe_asynchsetup(struct dwc2_pipe *chan, usbh_asynch_callback_t callback, void *arg)
+{
+ size_t flags;
+ int ret = -ENODEV;
+
+ flags = usb_osal_enter_critical_section();
+ /* Is the device still connected? */
+
+ if (usbh_get_port_connect_status(1)) {
+ /* Yes.. then set waiter to indicate that we expect to be informed
+ * when either (1) the device is disconnected, or (2) the transfer
+ * completed.
+ */
+
+ chan->waiter = false;
+ chan->result = -EBUSY;
+ chan->xfrd = 0;
+ chan->callback = callback;
+ chan->arg = arg;
+
+ ret = 0;
+ }
+
+ usb_osal_leave_critical_section(flags);
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: dwc2_pipe_wait
+ *
+ * Description:
+ * Wait for a transfer on a channel to complete.
+ *
+ * Assumptions:
+ * Called from a normal thread context
+ *
+ ****************************************************************************/
+
+static int dwc2_pipe_wait(struct dwc2_pipe *chan, uint32_t timeout)
+{
+ int ret;
+
+ /* Loop, testing for an end of transfer condition. The channel 'result'
+ * was set to EBUSY and 'waiter' was set to true before the transfer;
+ * 'waiter' will be set to false and 'result' will be set appropriately
+ * when the transfer is completed.
+ */
+
+ if (chan->waiter) {
+ ret = usb_osal_sem_take(chan->waitsem, timeout);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
+ /* The transfer is complete re-enable interrupts and return the result */
+ ret = chan->result;
+
+ if (ret < 0) {
+ return ret;
+ }
+ return chan->xfrd;
+}
+
+/****************************************************************************
+ * Name: dwc2_pipe_wakeup
+ *
+ * Description:
+ * A channel transfer has completed... wakeup any threads waiting for the
+ * transfer to complete.
+ *
+ * Assumptions:
+ * This function is called from the transfer complete interrupt handler for
+ * the channel. Interrupts are disabled.
+ *
+ ****************************************************************************/
+
+static void dwc2_pipe_wakeup(struct dwc2_pipe *chan)
+{
+ usbh_asynch_callback_t callback;
+ void *arg;
+ int nbytes;
+
+ /* Is the transfer complete? */
+
+ if (chan->result != -EBUSY) {
+ /* Is there a thread waiting for this transfer to complete? */
+
+ if (chan->waiter) {
+ /* Wake'em up! */
+ chan->waiter = false;
+ usb_osal_sem_give(chan->waitsem);
+ }
+#ifdef CONFIG_USBHOST_ASYNCH
+ /* No.. is an asynchronous callback expected when the transfer
+ * completes?
+ */
+ else if (chan->callback) {
+ callback = chan->callback;
+ arg = chan->arg;
+ nbytes = chan->xfrd;
+ chan->callback = NULL;
+ chan->arg = NULL;
+ if (chan->result < 0) {
+ nbytes = chan->result;
+ }
+
+ callback(arg, nbytes);
+ }
+#endif
+ }
+}
+
+__WEAK void usb_hc_low_level_init(void)
+{
+}
+
+int usb_hc_sw_init(void)
+{
+ memset(&g_dwc2_hcd, 0, sizeof(struct dwc2_hcd));
+
+ for (uint8_t chidx = 0; chidx < CONFIG_USB_DWC2_CHANNELS; chidx++) {
+ g_dwc2_hcd.chan[chidx].exclsem = usb_osal_mutex_create();
+ g_dwc2_hcd.chan[chidx].waitsem = usb_osal_sem_create(0);
+ }
+
+ return 0;
+}
+
+int usb_hc_hw_init(void)
+{
+ int ret;
+
+ usb_hc_low_level_init();
+
+ USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
+
+ ret = usb_dwc2_core_init();
+ /* Force Host Mode*/
+ usb_dwc2_set_mode(USB_OTG_MODE_HOST);
+ usb_osal_msleep(50);
+
+ /* Restart the Phy Clock */
+ USB_OTG_PCGCCTL = 0U;
+
+#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) || \
+ defined(STM32F7) || defined(STM32H7)
+ /* Disable HW VBUS sensing */
+ USB_OTG_GLB->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
+#else
+ /*
+ * Disable HW VBUS sensing. VBUS is internally considered to be always
+ * at VBUS-Valid level (5V).
+ */
+ USB_OTG_GLB->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
+ USB_OTG_GLB->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
+ USB_OTG_GLB->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
+#endif
+ USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSPCS_0;
+ usbh_reset_port(1);
+
+ /* Set default Max speed support */
+ USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
+
+ ret = usb_dwc2_flush_txfifo(0x10U);
+ ret = usb_dwc2_flush_rxfifo();
+
+ /* Clear all pending HC Interrupts */
+ for (uint8_t i = 0U; i < CONFIG_USB_DWC2_CHANNELS; i++) {
+ USBx_HC(i)->HCINT = 0xFFFFFFFFU;
+ USBx_HC(i)->HCINTMSK = 0U;
+ }
+
+ usb_dwc2_drivebus(1);
+ usb_osal_msleep(200);
+
+ /* Disable all interrupts. */
+ USB_OTG_GLB->GINTMSK = 0U;
+
+ /* Clear any pending interrupts */
+ USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU;
+
+ /* set Rx FIFO size */
+ USB_OTG_GLB->GRXFSIZ = 0x200U;
+ USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U);
+ USB_OTG_GLB->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
+
+ USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
+ USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
+
+ /* Enable interrupts matching to the Host mode ONLY */
+ USB_OTG_GLB->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |
+ USB_OTG_GINTSTS_DISCINT |
+ USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
+
+ // USB_OTG_GLB->GINTMSK |=USB_OTG_GINTMSK_SOFM;
+
+ USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
+
+ return 0;
+}
+
+bool usbh_get_port_connect_status(const uint8_t port)
+{
+ __IO uint32_t hprt0;
+
+ hprt0 = USBx_HPRT0;
+
+ if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int usbh_reset_port(const uint8_t port)
+{
+ __IO uint32_t hprt0 = 0U;
+
+ hprt0 = USBx_HPRT0;
+
+ hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
+
+ USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
+ usb_osal_msleep(100U); /* See Note #1 */
+ USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
+ usb_osal_msleep(10U);
+ return 0;
+}
+
+uint8_t usbh_get_port_speed(const uint8_t port)
+{
+ __IO uint32_t hprt0 = 0U;
+ uint8_t speed;
+
+ hprt0 = USBx_HPRT0;
+
+ speed = (hprt0 & USB_OTG_HPRT_PSPD) >> 17;
+
+ if (speed == HPRT0_PRTSPD_HIGH_SPEED) {
+ return USB_SPEED_HIGH;
+ } else if (speed == HPRT0_PRTSPD_FULL_SPEED) {
+ return USB_SPEED_FULL;
+ } else if (speed == HPRT0_PRTSPD_LOW_SPEED) {
+ return USB_SPEED_LOW;
+ } else {
+ return USB_SPEED_UNKNOWN;
+ }
+}
+
+int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uint8_t speed)
+{
+ struct dwc2_pipe *chan;
+ int chidx;
+ int ret;
+
+ chidx = (int)ep;
+
+ chan = &g_dwc2_hcd.chan[chidx];
+ ret = usb_osal_mutex_take(chan->exclsem);
+ if (ret < 0) {
+ return ret;
+ }
+ chan->dev_addr = dev_addr;
+ chan->ep_mps = ep_mps;
+ chan->speed = speed;
+ usb_osal_mutex_give(chan->exclsem);
+ return 0;
+}
+
+int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
+{
+ struct dwc2_pipe *chan;
+ struct usbh_hubport *hport;
+ int chidx;
+ uint8_t speed;
+
+ hport = ep_cfg->hport;
+
+ chidx = dwc2_pipe_alloc();
+
+ chan = &g_dwc2_hcd.chan[chidx];
+ chan->ep_addr = ep_cfg->ep_addr;
+ chan->ep_mps = ep_cfg->ep_mps;
+ chan->ep_type = ep_cfg->ep_type;
+ chan->dev_addr = hport->dev_addr;
+ chan->speed = hport->speed;
+ *ep = (usbh_epinfo_t)chidx;
+
+ if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) {
+ chan->data_pid = HC_PID_DATA1;
+ } else {
+ dwc2_pipe_init(chidx, chan->dev_addr, ep_cfg->ep_addr, ep_cfg->ep_type, chan->ep_mps, chan->speed);
+ chan->data_pid = HC_PID_DATA0;
+ }
+
+ return 0;
+}
+
+int usbh_ep_free(usbh_epinfo_t ep)
+{
+ int chidx;
+
+ chidx = (int)ep;
+ dwc2_pipe_free(chidx);
+ return 0;
+}
+
+int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint8_t *buffer)
+{
+ struct dwc2_pipe *chan;
+ int chidx;
+ int ret;
+
+ chidx = (int)ep;
+
+ chan = &g_dwc2_hcd.chan[chidx];
+ ret = usb_osal_mutex_take(chan->exclsem);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = dwc2_pipe_waitsetup(chan);
+ if (ret < 0) {
+ goto error_out;
+ }
+
+ chan->waiter = true;
+ chan->result = -EBUSY;
+ chan->num_packets = usb_dwc2_calculate_packet_num(8, chan->ep_addr, chan->ep_mps, &chan->xferlen);
+ dwc2_pipe_init(chidx, chan->dev_addr, 0x00, 0x00, chan->ep_mps, chan->speed);
+ usb_dwc2_pipe_transfer(chidx, 0x00, (uint32_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
+ ret = dwc2_pipe_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
+ if (ret < 0) {
+ goto error_out;
+ }
+
+ if (setup->wLength && buffer) {
+ if (setup->bmRequestType & 0x80) {
+ chan->waiter = true;
+ chan->result = -EBUSY;
+ chan->num_packets = usb_dwc2_calculate_packet_num(setup->wLength, 0x80, chan->ep_mps, &chan->xferlen);
+ dwc2_pipe_init(chidx, chan->dev_addr, 0x80, 0x00, chan->ep_mps, chan->speed);
+ usb_dwc2_pipe_transfer(chidx, 0x80, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ ret = dwc2_pipe_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
+ if (ret < 0) {
+ goto error_out;
+ }
+ chan->waiter = true;
+ chan->result = -EBUSY;
+ chan->num_packets = usb_dwc2_calculate_packet_num(0, 0x00, chan->ep_mps, &chan->xferlen);
+ dwc2_pipe_init(chidx, chan->dev_addr, 0x00, 0x00, chan->ep_mps, chan->speed);
+ usb_dwc2_pipe_transfer(chidx, 0x00, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ ret = dwc2_pipe_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
+ if (ret < 0) {
+ goto error_out;
+ }
+ } else {
+ chan->waiter = true;
+ chan->result = -EBUSY;
+ chan->num_packets = usb_dwc2_calculate_packet_num(setup->wLength, 0x00, chan->ep_mps, &chan->xferlen);
+ dwc2_pipe_init(chidx, chan->dev_addr, 0x00, 0x00, chan->ep_mps, chan->speed);
+ usb_dwc2_pipe_transfer(chidx, 0x00, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ ret = dwc2_pipe_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
+ if (ret < 0) {
+ goto error_out;
+ }
+ chan->waiter = true;
+ chan->result = -EBUSY;
+ chan->num_packets = usb_dwc2_calculate_packet_num(0, 0x80, chan->ep_mps, &chan->xferlen);
+ dwc2_pipe_init(chidx, chan->dev_addr, 0x80, 0x00, chan->ep_mps, chan->speed);
+ usb_dwc2_pipe_transfer(chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ ret = dwc2_pipe_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
+ if (ret < 0) {
+ goto error_out;
+ }
+ }
+ } else {
+ chan->waiter = true;
+ chan->result = -EBUSY;
+ chan->num_packets = usb_dwc2_calculate_packet_num(0, 0x80, chan->ep_mps, &chan->xferlen);
+ dwc2_pipe_init(chidx, chan->dev_addr, 0x80, 0x00, chan->ep_mps, chan->speed);
+ usb_dwc2_pipe_transfer(chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ ret = dwc2_pipe_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
+ if (ret < 0) {
+ goto error_out;
+ }
+ }
+ usb_osal_mutex_give(chan->exclsem);
+ return ret;
+error_out:
+ chan->waiter = false;
+ usb_osal_mutex_give(chan->exclsem);
+ return ret;
+}
+
+int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
+{
+ struct dwc2_pipe *chan;
+ int chidx;
+ int ret;
+
+ chidx = (int)ep;
+
+ chan = &g_dwc2_hcd.chan[chidx];
+ ret = usb_osal_mutex_take(chan->exclsem);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = dwc2_pipe_waitsetup(chan);
+ if (ret < 0) {
+ goto error_out;
+ }
+
+ chan->num_packets = usb_dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen);
+ usb_dwc2_pipe_transfer(chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid);
+ ret = dwc2_pipe_wait(chan, timeout);
+ if (ret < 0) {
+ goto error_out;
+ }
+
+ usb_osal_mutex_give(chan->exclsem);
+ return ret;
+error_out:
+ chan->waiter = false;
+ usb_osal_mutex_give(chan->exclsem);
+ return ret;
+}
+
+int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
+{
+ struct dwc2_pipe *chan;
+ int chidx;
+ int ret;
+
+ chidx = (int)ep;
+
+ chan = &g_dwc2_hcd.chan[chidx];
+ ret = usb_osal_mutex_take(chan->exclsem);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = dwc2_pipe_waitsetup(chan);
+ if (ret < 0) {
+ goto error_out;
+ }
+
+ chan->num_packets = usb_dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen);
+ usb_dwc2_pipe_transfer(chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid);
+ ret = dwc2_pipe_wait(chan, timeout);
+ if (ret < 0) {
+ goto error_out;
+ }
+ usb_osal_mutex_give(chan->exclsem);
+ return ret;
+error_out:
+ chan->waiter = false;
+ usb_osal_mutex_give(chan->exclsem);
+ return ret;
+}
+
+int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg)
+{
+ struct dwc2_pipe *chan;
+ int chidx;
+ int ret;
+
+ chidx = (int)ep;
+
+ chan = &g_dwc2_hcd.chan[chidx];
+ ret = usb_osal_mutex_take(chan->exclsem);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = dwc2_pipe_asynchsetup(chan, callback, arg);
+ if (ret < 0) {
+ goto error_out;
+ }
+
+ chan->num_packets = usb_dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen);
+ usb_dwc2_pipe_transfer(chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid);
+
+ return 0;
+error_out:
+ usb_osal_mutex_give(chan->exclsem);
+ return ret;
+}
+
+int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg)
+{
+ struct dwc2_pipe *chan;
+ int chidx;
+ int ret;
+
+ chidx = (int)ep;
+
+ chan = &g_dwc2_hcd.chan[chidx];
+ ret = usb_osal_mutex_take(chan->exclsem);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = dwc2_pipe_asynchsetup(chan, callback, arg);
+ if (ret < 0) {
+ goto error_out;
+ }
+
+ chan->num_packets = usb_dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen);
+ usb_dwc2_pipe_transfer(chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid);
+
+ return 0;
+error_out:
+ usb_osal_mutex_give(chan->exclsem);
+ return ret;
+}
+
+int usb_ep_cancel(usbh_epinfo_t ep)
+{
+ struct dwc2_pipe *chan;
+ int chidx;
+ int ret;
+ size_t flags;
+#ifdef CONFIG_USBHOST_ASYNCH
+ usbh_asynch_callback_t callback;
+ void *arg;
+#endif
+
+ chidx = (int)ep;
+ chan = &g_dwc2_hcd.chan[chidx];
+
+ flags = usb_osal_enter_critical_section();
+
+ chan->result = -ESHUTDOWN;
+#ifdef CONFIG_USBHOST_ASYNCH
+ /* Extract the callback information */
+ callback = chan->callback;
+ arg = chan->arg;
+ chan->callback = NULL;
+ chan->arg = NULL;
+ chan->xfrd = 0;
+#endif
+ usb_osal_leave_critical_section(flags);
+
+ /* Is there a thread waiting for this transfer to complete? */
+
+ if (chan->waiter) {
+ /* Wake'em up! */
+ chan->waiter = false;
+ usb_osal_sem_give(chan->waitsem);
+ }
+#ifdef CONFIG_USBHOST_ASYNCH
+ /* No.. is an asynchronous callback expected when the transfer completes? */
+ else if (callback) {
+ /* Then perform the callback */
+ callback(arg, -ESHUTDOWN);
+ }
+#endif
+ return 0;
+}
+
+void usb_dwc2_reset_handler(void *arg)
+{
+ usbh_reset_port(1);
+}
+
+//static void usb_dwc2_rxqlvl_irq_handler(void)
+//{
+// uint32_t pktsts;
+// uint32_t pktcnt;
+// uint32_t GrxstspReg;
+// uint32_t xferSizePktCnt;
+// uint32_t tmpreg;
+// uint32_t ch_num;
+// uint32_t len32b;
+// uint32_t *pdest;
+// struct dwc2_pipe *chan;
+
+// GrxstspReg = USB_OTG_GLB->GRXSTSP;
+// ch_num = GrxstspReg & USB_OTG_GRXSTSP_EPNUM;
+// pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17;
+// pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4;
+
+// chan = &g_dwc2_hcd.chan[ch_num];
+// switch (pktsts) {
+// case GRXSTS_PKTSTS_IN:
+// /* Read the data into the host buffer. */
+// if ((pktcnt > 0U) && (chan->buffer != NULL)) {
+// len32b = ((uint32_t)pktcnt + 3U) / 4U;
+
+// pdest = (uint32_t *)chan->buffer;
+
+// for (uint8_t i = 0U; i < len32b; i++) {
+// *pdest = USB_OTG_FIFO(0U);
+// pdest++;
+// }
+
+// chan->buffer += pktcnt;
+// chan->xfrd += pktcnt;
+// chan->buflen -= pktcnt;
+
+// if (chan->buflen == 0) {
+// }
+// }
+// break;
+
+// case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
+// break;
+
+// case GRXSTS_PKTSTS_IN_XFER_COMP:
+// case GRXSTS_PKTSTS_CH_HALTED:
+// default:
+// break;
+// }
+//}
+
+static void usb_dwc2_inchan_irq_handler(uint8_t ch_num)
+{
+ uint32_t chan_intstatus;
+ struct dwc2_pipe *chan;
+
+ chan_intstatus = (USBx_HC(ch_num)->HCINT) & (USBx_HC((uint32_t)ch_num)->HCINTMSK);
+
+ chan = &g_dwc2_hcd.chan[ch_num];
+
+ if ((chan_intstatus & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) {
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
+ usb_dwc2_halt(ch_num);
+ chan->result = 0;
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ } else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ chan->result = -EIO;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EPERM;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
+ } else if ((chan_intstatus & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EAGAIN;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
+ } else if ((chan_intstatus & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) {
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
+ } else if ((chan_intstatus & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EAGAIN;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
+ } else if ((chan_intstatus & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EIO;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EIO;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EPIPE;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EIO;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) {
+ USB_MASK_HALT_HC_INT(ch_num);
+
+ if (chan->result == 0) {
+ uint32_t count = chan->xferlen - (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); /* size that has received */
+ uint32_t has_sent_packets = chan->num_packets - ((USBx_HC(ch_num)->HCTSIZ & USB_OTG_DIEPTSIZ_PKTCNT) >> 19); /*how many packets has sent*/
+
+ chan->xfrd += count;
+
+ if ((has_sent_packets % 2) == 1) /* Flip in odd numbers */
+ {
+ if (chan->data_pid == HC_PID_DATA0) {
+ chan->data_pid = HC_PID_DATA1;
+ } else {
+ chan->data_pid = HC_PID_DATA0;
+ }
+ }
+ chan->result = 0;
+ }
+ dwc2_pipe_wakeup(chan);
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
+ }
+}
+
+static void usb_dwc2_outchan_irq_handler(uint8_t ch_num)
+{
+ uint32_t chan_intstatus;
+ struct dwc2_pipe *chan;
+ uint16_t buflen;
+
+ chan_intstatus = (USBx_HC(ch_num)->HCINT) & (USBx_HC((uint32_t)ch_num)->HCINTMSK);
+
+ chan = &g_dwc2_hcd.chan[ch_num];
+
+ if ((chan_intstatus & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) {
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
+ usb_dwc2_halt(ch_num);
+ chan->result = 0;
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ } else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ chan->result = -EIO;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EPERM;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
+ } else if ((chan_intstatus & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EAGAIN;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
+ } else if ((chan_intstatus & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) {
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
+ } else if ((chan_intstatus & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EAGAIN;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
+ } else if ((chan_intstatus & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EIO;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EIO;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EPIPE;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) {
+ USB_UNMASK_HALT_HC_INT(ch_num);
+ usb_dwc2_halt(ch_num);
+ chan->result = -EIO;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
+ } else if ((chan_intstatus & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) {
+ USB_MASK_HALT_HC_INT(ch_num);
+
+ if (chan->result == 0) {
+ uint32_t count = (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); /* last send size */
+
+ if (count == chan->ep_mps) {
+ chan->xfrd += chan->num_packets * chan->ep_mps;
+ } else {
+ chan->xfrd += (chan->num_packets - 1) * chan->ep_mps + count;
+ }
+
+ if ((chan->num_packets % 2) == 1) /* Flip in odd numbers */
+ {
+ if (chan->data_pid == HC_PID_DATA0) {
+ chan->data_pid = HC_PID_DATA1;
+ } else {
+ chan->data_pid = HC_PID_DATA0;
+ }
+ }
+ chan->result = 0;
+ }
+ dwc2_pipe_wakeup(chan);
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
+ }
+}
+
+static void usb_dwc2_port_irq_handler(void)
+{
+ __IO uint32_t hprt0, hprt0_dup, regval;
+
+ /* Handle Host Port Interrupts */
+ hprt0 = USBx_HPRT0;
+ hprt0_dup = USBx_HPRT0;
+
+ hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
+
+ /* Check whether Port Connect detected */
+ if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) {
+ if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) {
+ usb_workqueue_submit(&g_hpworkq, &g_dwc2_hcd.work, usb_dwc2_reset_handler, NULL, 0);
+ }
+ hprt0_dup |= USB_OTG_HPRT_PCDET;
+ }
+
+ /* Check whether Port Enable Changed */
+ if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) {
+ hprt0_dup |= USB_OTG_HPRT_PENCHNG;
+
+ if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) {
+#if defined(CONFIG_USB_DWC2_ULPI_PHY)
+#else
+ if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) {
+ USBx_HOST->HFIR = 6000U;
+ if ((USBx_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCS_1) {
+ regval = USBx_HOST->HCFG;
+ regval &= ~USB_OTG_HCFG_FSLSPCS;
+ regval |= USB_OTG_HCFG_FSLSPCS_1;
+ USBx_HOST->HCFG = regval;
+ usb_workqueue_submit(&g_hpworkq, &g_dwc2_hcd.work, usb_dwc2_reset_handler, NULL, 0);
+ }
+ } else {
+ USBx_HOST->HFIR = 48000U;
+ if ((USBx_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCS_0) {
+ regval = USBx_HOST->HCFG;
+ regval &= ~USB_OTG_HCFG_FSLSPCS;
+ regval |= USB_OTG_HCFG_FSLSPCS_0;
+ USBx_HOST->HCFG = regval;
+ usb_workqueue_submit(&g_hpworkq, &g_dwc2_hcd.work, usb_dwc2_reset_handler, NULL, 0);
+ }
+ }
+#endif
+
+ if (!g_dwc2_hcd.connected) {
+ g_dwc2_hcd.connected = true;
+ usbh_event_notify_handler(USBH_EVENT_CONNECTED, 1);
+ }
+ } else {
+ if (g_dwc2_hcd.connected) {
+ g_dwc2_hcd.connected = false;
+
+ for (int chidx = 0; chidx < CONFIG_USB_DWC2_CHANNELS; chidx++) {
+ struct dwc2_pipe *chan;
+ chan = &g_dwc2_hcd.chan[chidx];
+ if ((chan->ep_type == 0x00) && chan->waiter) {
+ chan->waiter = false;
+ usb_osal_sem_give(chan->waitsem);
+ }
+ }
+ usbh_event_notify_handler(USBH_EVENT_DISCONNECTED, 1);
+ }
+ }
+ }
+
+ /* Check for an overcurrent */
+ if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) {
+ hprt0_dup |= USB_OTG_HPRT_POCCHNG;
+ }
+ /* Clear Port Interrupts */
+ USBx_HPRT0 = hprt0_dup;
+}
+
+void USBH_IRQHandler(void)
+{
+ uint32_t gint_status, chan_int;
+ gint_status = usb_dwc2_get_glb_intstatus();
+ if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_HOST) {
+ /* Avoid spurious interrupt */
+ if (gint_status == 0) {
+ return;
+ }
+
+ if (gint_status & USB_OTG_GINTSTS_HPRTINT) {
+ usb_dwc2_port_irq_handler();
+ }
+ if (gint_status & USB_OTG_GINTSTS_DISCINT) {
+ USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_DISCINT;
+ }
+ // if (gint_status & USB_OTG_GINTSTS_RXFLVL) {
+ // USB_MASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
+ // usb_dwc2_rxqlvl_irq_handler();
+ // USB_UNMASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
+ // }
+ if (gint_status & USB_OTG_GINTSTS_HCINT) {
+ chan_int = (USBx_HOST->HAINT & USBx_HOST->HAINTMSK) & 0xFFFFU;
+ for (uint8_t i = 0U; i < CONFIG_USB_DWC2_CHANNELS; i++) {
+ if ((chan_int & (1UL << (i & 0xFU))) != 0U) {
+ if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR) {
+ usb_dwc2_inchan_irq_handler(i);
+ } else {
+ usb_dwc2_outchan_irq_handler(i);
+ }
+ }
+ }
+ USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_HCINT;
+ }
+ if (gint_status & USB_OTG_GINTSTS_SOF) {
+ USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_SOF;
+ }
+ }
+} \ No newline at end of file
diff --git a/port/synopsys/usb_dc_synopsys.c b/port/synopsys/usb_dc_synopsys.c
deleted file mode 100644
index 25f08e6b..00000000
--- a/port/synopsys/usb_dc_synopsys.c
+++ /dev/null
@@ -1,696 +0,0 @@
-#include "usbd_core.h"
-#include "usb_synopsys_reg.h"
-
-#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL)
-#ifndef USBD_IRQHandler
-#define USBD_IRQHandler OTG_HS_IRQHandler
-#endif
-
-#ifndef USB_BASE
-#define USB_BASE (0x40040000UL)
-#endif
-
-#ifndef USB_NUM_BIDIR_ENDPOINTS
-#define USB_NUM_BIDIR_ENDPOINTS 6 /* define with minimum value*/
-#endif
-
-#ifndef USB_RAM_SIZE
-#define USB_RAM_SIZE 4096 /* define with minimum value*/
-#endif
-
-#else
-#ifndef USBD_IRQHandler
-#define USBD_IRQHandler OTG_FS_IRQHandler
-#endif
-
-#ifndef USB_BASE
-#define USB_BASE (0x50000000UL)
-#endif
-
-#ifndef USB_NUM_BIDIR_ENDPOINTS
-#define USB_NUM_BIDIR_ENDPOINTS 4 /* define with minimum value*/
-#endif
-
-#ifndef USB_RAM_SIZE
-#define USB_RAM_SIZE 1280 /* define with minimum value*/
-#endif
-
-#endif
-
-#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL)
-/*FIFO sizes in bytes (total available memory for FIFOs is 4 kB)*/
-#ifndef CONFIG_USB_RX_FIFO_SIZE
-#define CONFIG_USB_RX_FIFO_SIZE (1024U)
-#endif
-#ifndef CONFIG_USB_TX0_FIFO_SIZE
-#define CONFIG_USB_TX0_FIFO_SIZE (64U)
-#endif
-#ifndef CONFIG_USB_TX1_FIFO_SIZE
-#define CONFIG_USB_TX1_FIFO_SIZE (1024U)
-#endif
-#ifndef CONFIG_USB_TX2_FIFO_SIZE
-#define CONFIG_USB_TX2_FIFO_SIZE (512U)
-#endif
-#ifndef CONFIG_USB_TX3_FIFO_SIZE
-#define CONFIG_USB_TX3_FIFO_SIZE (256U)
-#endif
-#ifndef CONFIG_USB_TX4_FIFO_SIZE
-#define CONFIG_USB_TX4_FIFO_SIZE (256U)
-#endif
-#ifndef CONFIG_USB_TX5_FIFO_SIZE
-#define CONFIG_USB_TX5_FIFO_SIZE (256U)
-#endif
-#else
-/*FIFO sizes in bytes (total available memory for FIFOs is 1.25kB)*/
-#ifndef CONFIG_USB_RX_FIFO_SIZE
-#define CONFIG_USB_RX_FIFO_SIZE (640U)
-#endif
-#ifndef CONFIG_USB_TX0_FIFO_SIZE
-#define CONFIG_USB_TX0_FIFO_SIZE (64U)
-#endif
-#ifndef CONFIG_USB_TX1_FIFO_SIZE
-#define CONFIG_USB_TX1_FIFO_SIZE (256U)
-#endif
-#ifndef CONFIG_USB_TX2_FIFO_SIZE
-#define CONFIG_USB_TX2_FIFO_SIZE (160U)
-#endif
-#ifndef CONFIG_USB_TX3_FIFO_SIZE
-#define CONFIG_USB_TX3_FIFO_SIZE (160U)
-#endif
-#endif
-
-#ifndef CONFIG_USB_TURNAROUND_TIME
-#define CONFIG_USB_TURNAROUND_TIME 6
-#endif
-
-/* Endpoint state */
-struct usb_dc_ep_state {
- /** Endpoint max packet size */
- uint16_t ep_mps;
- /** Endpoint Transfer Type.
- * May be Bulk, Interrupt, Control or Isochronous
- */
- uint8_t ep_type;
- uint8_t ep_stalled; /** Endpoint stall flag */
-};
-
-/* Driver state */
-struct usb_dc_config_priv {
- USB_OTG_GlobalTypeDef *Instance; /*!< Register base address */
- volatile uint32_t grxstsp;
- struct usb_dc_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
- struct usb_dc_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
-} usb_dc_cfg;
-
-static int usb_flush_rxfifo(USB_OTG_GlobalTypeDef *USBx);
-static int usb_flush_txfifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num);
-static void usb_set_txfifo(USB_OTG_GlobalTypeDef *USBx, uint8_t fifo, uint16_t size);
-
-__WEAK void usb_dc_low_level_init(void)
-{
-}
-
-__WEAK void usb_dc_low_level_deinit(void)
-{
-}
-
-int usb_dc_init(void)
-{
- uint32_t USBx_BASE;
- uint32_t count = 0U;
-
- memset(&usb_dc_cfg, 0, sizeof(struct usb_dc_config_priv));
-
- usb_dc_cfg.Instance = (USB_OTG_GlobalTypeDef *)USB_BASE;
-
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
-
- usb_dc_low_level_init();
-
- USBx_BASE = (uint32_t)USBx;
-
- USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
-
- USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
-#if defined(CONFIG_USB_HS)
- USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
-
- /* Init The ULPI Interface */
- USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
-
- /* Select vbus source */
- USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
-
- //USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
-
-#else
- /* Select FS Embedded PHY */
- USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
- /* Activate the USB Transceiver */
- USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
-
-#endif
-
- /* Reset after a PHY select and set Host mode */
- /* Wait for AHB master IDLE state. */
- do {
- if (++count > 200000U) {
- return -1;
- }
- } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
-
- /* Core Soft Reset */
- count = 0U;
- USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
-
- do {
- if (++count > 200000U) {
- return -1;
- }
- } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
-
- /* Force Device Mode*/
- USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
-
- USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
- USBx->GUSBCFG |= (uint32_t)((CONFIG_USB_TURNAROUND_TIME << 10) & USB_OTG_GUSBCFG_TRDT);
-
- for (uint8_t i = 0U; i < 15U; i++) {
- USBx->DIEPTXF[i] = 0U;
- }
-
-#ifdef CONFIG_USB_SYNOPSYS_NOVBUSSEN
- /* Deactivate VBUS Sensing B */
- USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
-
- /* B-peripheral session valid override enable */
- USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
- USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
-#else
- USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
- USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
- USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
-#endif
- /* Restart the Phy Clock */
- USBx_PCGCCTL = 0U;
-
- /* Device mode configuration */
- USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
-#if defined(CONFIG_USB_HS)
- /* Set Core speed to High speed mode */
- USBx_DEVICE->DCFG |= USB_OTG_SPEED_HIGH;
-#elif defined(CONFIG_USB_HS_IN_FULL)
- USBx_DEVICE->DCFG |= USB_OTG_SPEED_HIGH_IN_FULL;
-#else
- USBx_DEVICE->DCFG |= USB_OTG_SPEED_FULL;
-#endif
-
- usb_flush_txfifo(USBx, 0x10U);
- usb_flush_rxfifo(USBx);
-
- /* Clear all pending Device Interrupts */
- USBx_DEVICE->DIEPMSK = 0U;
- USBx_DEVICE->DOEPMSK = 0U;
- USBx_DEVICE->DAINTMSK = 0U;
-
- for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
- if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) {
- if (i == 0U) {
- USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
- } else {
- USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
- }
- } else {
- USBx_INEP(i)->DIEPCTL = 0U;
- }
-
- USBx_INEP(i)->DIEPTSIZ = 0U;
- USBx_INEP(i)->DIEPINT = 0xFB7FU;
- }
- for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
- if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) {
- if (i == 0U) {
- USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
- } else {
- USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
- }
- } else {
- USBx_OUTEP(i)->DOEPCTL = 0U;
- }
-
- USBx_OUTEP(i)->DOEPTSIZ = 0U;
- USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
- }
-
- /* Disable all interrupts. */
- USBx->GINTMSK = 0U;
-
- /* Clear any pending interrupts */
- USBx->GINTSTS = 0xBFFFFFFFU;
-
- /* Enable interrupts matching to the Device mode ONLY */
- USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM |
- USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_RXFLVLM |
- USB_OTG_GINTMSK_WUIM;
-#if 0
- USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
-#endif
- USBx_DEVICE->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM;
-
- USBx_DEVICE->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
-
- USBx->GRXFSIZ = (CONFIG_USB_RX_FIFO_SIZE / 4);
-#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL)
- usb_set_txfifo(USBx, 0, CONFIG_USB_TX0_FIFO_SIZE / 4);
- usb_set_txfifo(USBx, 1, CONFIG_USB_TX1_FIFO_SIZE / 4);
- usb_set_txfifo(USBx, 2, CONFIG_USB_TX2_FIFO_SIZE / 4);
- usb_set_txfifo(USBx, 3, CONFIG_USB_TX3_FIFO_SIZE / 4);
- usb_set_txfifo(USBx, 4, CONFIG_USB_TX4_FIFO_SIZE / 4);
- usb_set_txfifo(USBx, 5, CONFIG_USB_TX5_FIFO_SIZE / 4);
-#else
- usb_set_txfifo(USBx, 0, CONFIG_USB_TX0_FIFO_SIZE / 4);
- usb_set_txfifo(USBx, 1, CONFIG_USB_TX1_FIFO_SIZE / 4);
- usb_set_txfifo(USBx, 2, CONFIG_USB_TX2_FIFO_SIZE / 4);
- usb_set_txfifo(USBx, 3, CONFIG_USB_TX3_FIFO_SIZE / 4);
-#endif
- USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
- USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
-
- return 0;
-}
-
-int usb_dc_deinit(void)
-{
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
- uint32_t USBx_BASE = (uint32_t)USBx;
-
- usb_dc_low_level_deinit();
- /* Clear Pending interrupt */
- for (uint8_t i = 0U; i < 15U; i++) {
- USBx_INEP(i)->DIEPINT = 0xFB7FU;
- USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
- }
-
- /* Clear interrupt masks */
- USBx_DEVICE->DIEPMSK = 0U;
- USBx_DEVICE->DOEPMSK = 0U;
- USBx_DEVICE->DAINTMSK = 0U;
-
- /* Flush the FIFO */
- usb_flush_txfifo(USBx, 0x10U);
- usb_flush_rxfifo(USBx);
-
- USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
-
- return 0;
-}
-
-int usbd_set_address(const uint8_t addr)
-{
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
- uint32_t USBx_BASE = (uint32_t)USBx;
- USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
- USBx_DEVICE->DCFG |= ((uint32_t)addr << 4) & USB_OTG_DCFG_DAD;
- return 0;
-}
-
-int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
-{
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
- uint32_t USBx_BASE = (uint32_t)USBx;
- uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
-
- if (!ep_cfg) {
- return -1;
- }
-
- if (USB_EP_DIR_IS_OUT(ep_cfg->ep_addr)) {
- usb_dc_cfg.out_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
- usb_dc_cfg.out_ep[ep_idx].ep_type = ep_cfg->ep_type;
-
- USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx));
-
- USBx_OUTEP(ep_idx)->DOEPCTL |= (ep_cfg->ep_mps & USB_OTG_DOEPCTL_MPSIZ) |
- ((uint32_t)ep_cfg->ep_type << 18) |
- USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
- USB_OTG_DOEPCTL_USBAEP;
- /* EP enable */
- USBx_OUTEP(ep_idx)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
- } else {
- usb_dc_cfg.in_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
- usb_dc_cfg.in_ep[ep_idx].ep_type = ep_cfg->ep_type;
-
- USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx);
-
- USBx_INEP(ep_idx)->DIEPCTL |= (ep_cfg->ep_mps & USB_OTG_DIEPCTL_MPSIZ) |
- ((uint32_t)ep_cfg->ep_type << 18) | (ep_idx << 22) |
- USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
- USB_OTG_DIEPCTL_USBAEP;
- }
- return 0;
-}
-int usbd_ep_close(const uint8_t ep)
-{
- return 0;
-}
-int usbd_ep_set_stall(const uint8_t ep)
-{
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
- uint32_t USBx_BASE = (uint32_t)USBx;
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
-
- if (USB_EP_DIR_IS_OUT(ep)) {
- USBx_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
- } else {
- USBx_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
- }
-
- return 0;
-}
-int usbd_ep_clear_stall(const uint8_t ep)
-{
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
- uint32_t USBx_BASE = (uint32_t)USBx;
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
-
- if (USB_EP_DIR_IS_OUT(ep)) {
- USBx_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
- } else {
- USBx_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
- }
- return 0;
-}
-int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
-{
- if (USB_EP_DIR_IS_OUT(ep)) {
- } else {
- }
- return 0;
-}
-
-int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *ret_bytes)
-{
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
- uint32_t USBx_BASE = (uint32_t)USBx;
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
- uint32_t len32b;
-
- if (!data && data_len) {
- return -1;
- }
-
- if (!data_len) {
- USBx_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
- USBx_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
- USBx_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
- /* EP enable, IN data in FIFO */
- USBx_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
-
- return 0;
- }
-
- if (data_len > usb_dc_cfg.in_ep[ep_idx].ep_mps) {
- data_len = usb_dc_cfg.in_ep[ep_idx].ep_mps;
- }
-
- /* Program the transfer size and packet count
- * as follows: xfersize = N * maxpacket +
- * short_packet pktcnt = N + (short_packet
- * exist ? 1 : 0)
- */
- USBx_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
- USBx_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
- USBx_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
- //USBx_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((data_len + usb_dc_cfg.in_ep[ep_idx].ep_mps - 1U) / usb_dc_cfg.in_ep[ep_idx].ep_mps) << 19));
- USBx_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len);
- /* EP enable, IN data in FIFO */
- USBx_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
-
- if (usb_dc_cfg.in_ep[ep_idx].ep_type == EP_TYPE_ISOC) {
- USBx_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
- USBx_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
-
- if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U) {
- USBx_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
- } else {
- USBx_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
- }
- }
-
- len32b = (data_len + 3U) / 4U;
-
- while (USBx_INEP(ep_idx)->DTXFSTS < len32b) {
- }
- for (uint8_t i = 0U; i < len32b; i++) {
- USBx_DFIFO(ep_idx) = ((uint32_t *)data)[i];
- }
-
- if (ret_bytes) {
- *ret_bytes = data_len;
- }
-
- return 0;
-}
-
-int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes)
-{
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
- uint32_t USBx_BASE = (uint32_t)USBx;
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
- uint32_t *pdest = (uint32_t *)data;
- uint32_t len32b;
- uint32_t read_count;
- uint32_t pktcnt;
- if (!data && max_data_len) {
- return -1;
- }
-
- if (!max_data_len) {
- if (ep_idx != 0) {
- /* Program the transfer size and packet count as follows:
- * pktcnt = N
- * xfersize = N * maxpacket
- */
- pktcnt = (uint16_t)((max_data_len + usb_dc_cfg.out_ep[ep_idx].ep_mps - 1U) / usb_dc_cfg.out_ep[ep_idx].ep_mps);
- USBx_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
- USBx_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
- USBx_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
- USBx_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & usb_dc_cfg.out_ep[ep_idx].ep_mps * pktcnt);
- /* EP enable */
- USBx_OUTEP(ep_idx)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
- }
-
- return 0;
- }
-
- if (max_data_len > usb_dc_cfg.out_ep[ep_idx].ep_mps) {
- max_data_len = usb_dc_cfg.out_ep[ep_idx].ep_mps;
- }
-
- read_count = (usb_dc_cfg.grxstsp & USB_OTG_GRXSTSP_BCNT) >> 4;
- read_count = MIN(read_count, max_data_len);
-
- len32b = ((uint32_t)read_count + 3U) / 4U;
-
- for (uint8_t i = 0U; i < len32b; i++) {
- *pdest = USBx_DFIFO(0U);
- pdest++;
- }
-
- if (read_bytes) {
- *read_bytes = read_count;
- }
-
- usb_dc_cfg.grxstsp = 0;
- return 0;
-}
-
-void USBD_IRQHandler(void)
-{
- USB_OTG_GlobalTypeDef *USBx = usb_dc_cfg.Instance;
- uint32_t gint_status, temp, epnum, ep_intr, epint;
- uint32_t USBx_BASE = (uint32_t)USBx;
- gint_status = USBx->GINTSTS;
-
- if ((gint_status & 0x1U) == USB_OTG_MODE_DEVICE) {
- if (gint_status == 0) {
- return;
- }
- /* Handle RxQLevel Interrupt */
- if (gint_status & USB_OTG_GINTSTS_RXFLVL) {
- USB_MASK_INTERRUPT(USBx, USB_OTG_GINTSTS_RXFLVL);
- temp = USBx->GRXSTSP;
- usb_dc_cfg.grxstsp = temp;
- epnum = temp & USB_OTG_GRXSTSP_EPNUM;
- if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) {
- if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U) {
- if (epnum == 0) {
- usbd_event_notify_handler(USBD_EVENT_EP0_OUT_NOTIFY, NULL);
- } else {
- usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(epnum | USB_EP_DIR_OUT));
- }
- }
- } else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_SETUP_UPDT) {
- uint8_t len = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
- usbd_event_notify_handler(USBD_EVENT_SETUP_NOTIFY, NULL);
- } else {
- /* ... */
- }
- USB_UNMASK_INTERRUPT(USBx, USB_OTG_GINTSTS_RXFLVL);
- }
-
- if (gint_status & USB_OTG_GINTSTS_OEPINT) {
- epnum = 0;
- /* Read in the device interrupt bits */
- ep_intr = USBx_DEVICE->DAINT;
- ep_intr &= USBx_DEVICE->DAINTMSK;
- ep_intr >>= 16;
-
- while (ep_intr != 0U) {
- if ((ep_intr & 0x1U) != 0U) {
- epint = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
-
- epint &= USBx_DEVICE->DOEPMSK;
- if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) {
- USBx_OUTEP(epnum)->DOEPINT = (USB_OTG_DOEPINT_STUP);
-
- USBx_OUTEP(epnum)->DOEPTSIZ = 1U << USB_OTG_DOEPTSIZ_PKTCNT_Pos |
- (USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_MPSIZ) << USB_OTG_DOEPTSIZ_XFRSIZ_Pos;
- USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
- }
- if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) {
- USBx_OUTEP(epnum)->DOEPINT = (USB_OTG_DOEPINT_XFRC);
-
- if (epnum == 0) {
- USBx_OUTEP(epnum)->DOEPTSIZ = 1U << USB_OTG_DOEPTSIZ_PKTCNT_Pos |
- (USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_MPSIZ) << USB_OTG_DOEPTSIZ_XFRSIZ_Pos;
- USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
- }
- }
- }
- ep_intr >>= 1U;
- epnum++;
- }
- }
- if (gint_status & USB_OTG_GINTSTS_IEPINT) {
- epnum = 0U;
- ep_intr = USBx_DEVICE->DAINT & 0xFFFF;
- ep_intr &= USBx_DEVICE->DAINTMSK;
- while (ep_intr != 0U) {
- if ((ep_intr & 0x1U) != 0U) {
- epint = USBx_INEP((uint32_t)epnum)->DIEPINT;
- epint &= USBx_DEVICE->DIEPMSK;
-
- if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) {
- USBx_INEP(epnum)->DIEPINT = USB_OTG_DIEPINT_XFRC;
- if (epnum == 0) {
- usbd_event_notify_handler(USBD_EVENT_EP0_IN_NOTIFY, NULL);
- } else {
- usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(epnum | USB_EP_DIR_IN));
- }
- }
- }
- ep_intr >>= 1U;
- epnum++;
- }
- }
- if (gint_status & USB_OTG_GINTSTS_USBRST) {
- USBx->GINTSTS |= USB_OTG_GINTSTS_USBRST;
- USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
-
- usb_flush_txfifo(USBx, 0x10U);
- usb_flush_rxfifo(USBx);
- for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
- USBx_INEP(i)->DIEPINT = 0xFB7FU;
- USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
- USBx_INEP(i)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
- USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
- USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
- USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
- }
- USBx_DEVICE->DAINTMSK |= 0x10001U;
-
- USBx_OUTEP(0U)->DOEPTSIZ = 0U;
- USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
- USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
- USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
- USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
-
- usbd_event_notify_handler(USBD_EVENT_RESET, NULL);
- }
- if (gint_status & USB_OTG_GINTSTS_ENUMDNE) {
- USBx->GINTSTS |= USB_OTG_GINTSTS_ENUMDNE;
- //uint8_t speed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
- /* Set the MPS of the IN EP0 to 64 bytes */
- USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
-
- USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
- }
- if (gint_status & USB_OTG_GINTSTS_SOF) {
- USBx->GINTSTS |= USB_OTG_GINTSTS_SOF;
- }
- if (gint_status & USB_OTG_GINTSTS_USBSUSP) {
- USBx->GINTSTS |= USB_OTG_GINTSTS_USBSUSP;
- }
- }
-}
-
-static int usb_flush_rxfifo(USB_OTG_GlobalTypeDef *USBx)
-{
- uint32_t count = 0;
-
- USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
-
- do {
- if (++count > 200000U) {
- return -1;
- }
- } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
-
- return 0;
-}
-
-static int usb_flush_txfifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
-{
- uint32_t count = 0U;
-
- USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
-
- do {
- if (++count > 200000U) {
- return -1;
- }
- } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
-
- return 0;
-}
-
-static void usb_set_txfifo(USB_OTG_GlobalTypeDef *USBx, uint8_t fifo, uint16_t size)
-{
- uint8_t i;
- uint32_t Tx_Offset;
-
- /* TXn min size = 16 words. (n : Transmit FIFO index)
- When a TxFIFO is not used, the Configuration should be as follows:
- case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
- --> Txm can use the space allocated for Txn.
- case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
- --> Txn should be configured with the minimum space of 16 words
- The FIFO is used optimally when used TxFIFOs are allocated in the top
- of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
- When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
-
- Tx_Offset = USBx->GRXFSIZ;
-
- if (fifo == 0U) {
- USBx->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset;
- } else {
- Tx_Offset += (USBx->DIEPTXF0_HNPTXFSIZ) >> 16;
- for (i = 0U; i < (fifo - 1U); i++) {
- Tx_Offset += (USBx->DIEPTXF[i] >> 16);
- }
-
- /* Multiply Tx_Size by 2 to get higher performance */
- USBx->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset;
- }
-}
diff --git a/port/synopsys/usb_hc_synopsys.c b/port/synopsys/usb_hc_synopsys.c
deleted file mode 100644
index edd69c88..00000000
--- a/port/synopsys/usb_hc_synopsys.c
+++ /dev/null
@@ -1,928 +0,0 @@
-#include "usbh_core.h"
-#include "stm32f4xx_hal.h"
-
-#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL)
-HCD_HandleTypeDef hhcd_USB_OTG_HS;
-#ifndef USBH_IRQHandler
-#define USBH_IRQHandler OTG_HS_IRQHandler
-#endif
-#else
-HCD_HandleTypeDef hhcd_USB_OTG_FS;
-#ifndef USBH_IRQHandler
-#define USBH_IRQHandler OTG_FS_IRQHandler
-#endif
-#endif
-
-#ifndef CONFIG_USBHOST_CHANNELS
-#define CONFIG_USBHOST_CHANNELS 12 /* Number of host channels */
-#endif
-
-#define CONFIG_CONTROL_RETRY_COUNT 10
-
-#define USBH_PID_SETUP 0U
-#define USBH_PID_DATA 1U
-
-enum usb_synopsys_transfer_state {
- TRANSFER_IDLE = 0,
- TRANSFER_BUSY,
-};
-/* This structure retains the state of one host channel. NOTE: Since there
- * is only one channel operation active at a time, some of the fields in
- * in the structure could be moved in struct stm32_ubhost_s to achieve
- * some memory savings.
- */
-
-struct usb_synopsys_chan {
- bool inuse; /* True: This channel is "in use" */
- bool in; /* True: IN endpoint */
- uint8_t interval; /* Interrupt/isochronous EP polling interval */
- uint8_t transfer_state; /* Interrupt/isochronous EP transfer state */
- volatile int result; /* The result of the transfer */
- volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */
- volatile bool waiter; /* True: Thread is waiting for a channel event */
- usb_osal_sem_t waitsem; /* Channel wait semaphore */
- usb_osal_mutex_t exclsem; /* Support mutually exclusive access */
-#ifdef CONFIG_USBHOST_ASYNCH
- usbh_asynch_callback_t callback; /* Transfer complete callback */
- void *arg; /* Argument that accompanies the callback */
-#endif
-};
-
-/* A channel represents on uni-directional endpoint. So, in the case of the
- * bi-directional, control endpoint, there must be two channels to represent
- * the endpoint.
- */
-
-struct usb_synopsys_ctrlinfo {
- uint8_t inndx; /* EP0 IN control channel index */
- uint8_t outndx; /* EP0 OUT control channel index */
-};
-
-struct usb_synopsys_priv {
- HCD_HandleTypeDef *handle;
- volatile uint64_t sof_timer;
- volatile bool connected; /* Connected to device */
- struct usb_synopsys_chan chan[CONFIG_USBHOST_CHANNELS];
-} g_usbhost;
-
-/****************************************************************************
- * Name: usb_synopsys_chan_alloc
- *
- * Description:
- * Allocate a channel.
- *
- ****************************************************************************/
-
-static int usb_synopsys_chan_alloc(void)
-{
- int chidx;
-
- /* Search the table of channels */
-
- for (chidx = 0; chidx < CONFIG_USBHOST_CHANNELS; chidx++) {
- /* Is this channel available? */
- if (!g_usbhost.chan[chidx].inuse) {
- /* Yes... make it "in use" and return the index */
-
- g_usbhost.chan[chidx].inuse = true;
- return chidx;
- }
- }
-
- /* All of the channels are "in-use" */
-
- return -EBUSY;
-}
-
-/****************************************************************************
- * Name: usb_synopsys_chan_free
- *
- * Description:
- * Free a previoiusly allocated channel.
- *
- ****************************************************************************/
-
-static void usb_synopsys_chan_free(int chidx)
-{
- /* Halt the channel */
- HAL_HCD_HC_Halt(g_usbhost.handle, chidx);
- /* Mark the channel available */
-
- g_usbhost.chan[chidx].inuse = false;
-}
-
-/****************************************************************************
- * Name: usb_synopsys_chan_freeall
- *
- * Description:
- * Free all channels.
- *
- ****************************************************************************/
-
-static inline void usb_synopsys_chan_freeall(void)
-{
- uint8_t chidx;
-
- /* Free all host channels */
-
- for (chidx = 2; chidx < CONFIG_USBHOST_CHANNELS; chidx++) {
- usb_synopsys_chan_free(chidx);
- }
-}
-
-/****************************************************************************
- * Name: usb_synopsys_chan_waitsetup
- *
- * Description:
- * Set the request for the transfer complete event well BEFORE enabling
- * the transfer (as soon as we are absolutely committed to the transfer).
- * We do this to minimize race conditions. This logic would have to be
- * expanded if we want to have more than one packet in flight at a time!
- *
- * Assumptions:
- * Called from a normal thread context BEFORE the transfer has been
- * started.
- *
- ****************************************************************************/
-
-static int usb_synopsys_chan_waitsetup(struct usb_synopsys_chan *chan)
-{
- size_t flags;
- int ret = -ENODEV;
-
- flags = usb_osal_enter_critical_section();
-
- /* Is the device still connected? */
-
- if (g_usbhost.connected) {
- /* Yes.. then set waiter to indicate that we expect to be informed
- * when either (1) the device is disconnected, or (2) the transfer
- * completed.
- */
-
- chan->waiter = true;
- chan->result = -EBUSY;
- chan->xfrd = 0;
-#ifdef CONFIG_USBHOST_ASYNCH
- chan->callback = NULL;
- chan->arg = NULL;
-#endif
- ret = 0;
- }
- usb_osal_leave_critical_section(flags);
- return ret;
-}
-
-/****************************************************************************
- * Name: usb_synopsys_chan_asynchsetup
- *
- * Description:
- * Set the request for the transfer complete event well BEFORE enabling
- * the transfer (as soon as we are absolutely committed to the to avoid
- * transfer). We do this to minimize race conditions. This logic would
- * have to be expanded if we want to have more than one packet in flight
- * at a time!
- *
- * Assumptions:
- * Might be called from the level of an interrupt handler
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBHOST_ASYNCH
-static int usb_synopsys_chan_asynchsetup(struct usb_synopsys_chan *chan, usbh_asynch_callback_t callback, void *arg)
-{
- size_t flags;
- int ret = -ENODEV;
-
- flags = usb_osal_enter_critical_section();
- /* Is the device still connected? */
-
- if (g_usbhost.connected) {
- /* Yes.. then set waiter to indicate that we expect to be informed
- * when either (1) the device is disconnected, or (2) the transfer
- * completed.
- */
-
- chan->waiter = false;
- chan->result = -EBUSY;
- chan->xfrd = 0;
- chan->callback = callback;
- chan->arg = arg;
- ret = 0;
- }
-
- usb_osal_leave_critical_section(flags);
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: usb_synopsys_chan_wait
- *
- * Description:
- * Wait for a transfer on a channel to complete.
- *
- * Assumptions:
- * Called from a normal thread context
- *
- ****************************************************************************/
-
-static int usb_synopsys_chan_wait(struct usb_synopsys_chan *chan, uint32_t timeout)
-{
- int ret;
-
- /* Loop, testing for an end of transfer condition. The channel 'result'
- * was set to EBUSY and 'waiter' was set to true before the transfer;
- * 'waiter' will be set to false and 'result' will be set appropriately
- * when the transfer is completed.
- */
-
- if (chan->waiter) {
- ret = usb_osal_sem_take(chan->waitsem, timeout);
- if (ret < 0) {
- return ret;
- }
- }
-
- /* The transfer is complete re-enable interrupts and return the result */
- ret = chan->result;
-
- if (ret < 0) {
- return ret;
- }
- return chan->xfrd;
-}
-
-/****************************************************************************
- * Name: usb_synopsys_chan_wakeup
- *
- * Description:
- * A channel transfer has completed... wakeup any threads waiting for the
- * transfer to complete.
- *
- * Assumptions:
- * This function is called from the transfer complete interrupt handler for
- * the channel. Interrupts are disabled.
- *
- ****************************************************************************/
-
-static void usb_synopsys_chan_wakeup(struct usb_synopsys_chan *chan)
-{
- usbh_asynch_callback_t callback;
- void *arg;
- int nbytes;
-
- /* Is the transfer complete? */
-
- if (chan->result != -EBUSY) {
- /* Is there a thread waiting for this transfer to complete? */
-
- if (chan->waiter) {
- /* Wake'em up! */
- chan->waiter = false;
- usb_osal_sem_give(chan->waitsem);
- }
-#ifdef CONFIG_USBHOST_ASYNCH
- /* No.. is an asynchronous callback expected when the transfer
- * completes?
- */
- else if (chan->callback) {
- /* Handle continuation of IN/OUT pipes */
- if (chan->in) {
- callback = chan->callback;
- arg = chan->arg;
- nbytes = chan->xfrd;
- chan->callback = NULL;
- chan->arg = NULL;
- if (chan->result < 0) {
- nbytes = chan->result;
- }
-
- callback(arg, nbytes);
-
- } else {
- callback = chan->callback;
- arg = chan->arg;
- nbytes = chan->xfrd;
- chan->callback = NULL;
- chan->arg = NULL;
- if (chan->result < 0) {
- nbytes = chan->result;
- }
-
- callback(arg, nbytes);
- }
- }
-#endif
- }
-}
-
-__WEAK void usb_hc_low_level_init(void)
-{
-}
-
-int usb_hc_init(void)
-{
- g_usbhost.connected = 0;
- g_usbhost.sof_timer = 0;
-#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL)
- g_usbhost.handle = &hhcd_USB_OTG_HS;
- g_usbhost.handle->Instance = USB_OTG_HS;
-#else
- g_usbhost.handle = &hhcd_USB_OTG_FS;
- g_usbhost.handle->Instance = USB_OTG_FS;
-#endif
-
- g_usbhost.handle->Init.Host_channels = CONFIG_USBHOST_CHANNELS;
- g_usbhost.handle->Init.speed = HCD_SPEED_FULL;
- g_usbhost.handle->Init.dma_enable = DISABLE;
- g_usbhost.handle->Init.phy_itface = USB_OTG_EMBEDDED_PHY;
- g_usbhost.handle->Init.Sof_enable = DISABLE;
- g_usbhost.handle->Init.low_power_enable = DISABLE;
- g_usbhost.handle->Init.vbus_sensing_enable = DISABLE;
- g_usbhost.handle->Init.use_external_vbus = DISABLE;
- if (HAL_HCD_Init(g_usbhost.handle) != HAL_OK) {
- return -1;
- }
- HAL_HCD_Start(g_usbhost.handle);
- return 0;
-}
-
-bool usbh_get_port_connect_status(const uint8_t port)
-{
- USB_OTG_GlobalTypeDef *USBx = g_usbhost.handle->Instance;
- uint32_t USBx_BASE = (uint32_t)USBx;
- __IO uint32_t hprt0;
-
- hprt0 = USBx_HPRT0;
-
- if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) {
- return true;
- } else {
- return false;
- }
-}
-
-int usbh_reset_port(const uint8_t port)
-{
- HAL_HCD_ResetPort(g_usbhost.handle);
- return 0;
-}
-
-uint8_t usbh_get_port_speed(const uint8_t port)
-{
- if (HAL_HCD_GetCurrentSpeed(g_usbhost.handle) == 1) {
- return USB_SPEED_FULL;
- } else if (HAL_HCD_GetCurrentSpeed(g_usbhost.handle) == 2)
- return USB_SPEED_LOW;
- else
- return USB_SPEED_HIGH;
-}
-
-int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uint8_t speed)
-{
- struct usb_synopsys_chan *chan;
- struct usb_synopsys_ctrlinfo *ep0info;
- int ret;
-
- ep0info = (struct usb_synopsys_ctrlinfo *)ep;
-
- chan = &g_usbhost.chan[ep0info->outndx];
- ret = usb_osal_mutex_take(chan->exclsem);
- if (ret < 0) {
- return ret;
- }
-
- if (speed == USB_SPEED_FULL) {
- speed = 1;
- } else if (speed == USB_SPEED_LOW) {
- speed = 2;
- } else if (speed == USB_SPEED_HIGH) {
- speed = 0;
- }
-
- ret = HAL_HCD_HC_Init(g_usbhost.handle, ep0info->outndx, 0x00, dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_mps);
- ret = HAL_HCD_HC_Init(g_usbhost.handle, ep0info->inndx, 0x80, dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_mps);
- usb_osal_mutex_give(chan->exclsem);
- return ret;
-}
-
-int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
-{
- struct usb_synopsys_chan *chan;
- struct usb_synopsys_priv *priv = &g_usbhost;
- struct usb_synopsys_ctrlinfo *ep0;
- struct usbh_hubport *hport;
- int chidx;
- uint8_t speed;
-
- hport = ep_cfg->hport;
-
- if (hport->speed == USB_SPEED_FULL) {
- speed = 1;
- } else if (hport->speed == USB_SPEED_LOW) {
- speed = 2;
- } else if (hport->speed == USB_SPEED_HIGH) {
- speed = 0;
- }
-
- if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) {
- ep0 = usb_malloc(sizeof(struct usb_synopsys_ctrlinfo));
- memset(ep0, 0, sizeof(struct usb_synopsys_ctrlinfo));
-
- ep0->outndx = usb_synopsys_chan_alloc();
- ep0->inndx = usb_synopsys_chan_alloc();
-
- chan = &priv->chan[ep0->outndx];
- memset(chan, 0, sizeof(struct usb_synopsys_chan));
- chan->inuse = true;
- chan->waitsem = usb_osal_sem_create(0);
- chan->exclsem = usb_osal_mutex_create();
-
- chan = &priv->chan[ep0->inndx];
- memset(chan, 0, sizeof(struct usb_synopsys_chan));
- chan->inuse = true;
- chan->waitsem = usb_osal_sem_create(0);
-
- HAL_HCD_HC_Init(g_usbhost.handle, ep0->outndx, 0x00, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps);
- HAL_HCD_HC_Init(g_usbhost.handle, ep0->inndx, 0x80, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps);
-
- *ep = (usbh_epinfo_t)ep0;
-
- } else {
- chidx = usb_synopsys_chan_alloc();
-
- chan = &priv->chan[chidx];
- memset(chan, 0, sizeof(struct usb_synopsys_chan));
- chan->inuse = true;
- chan->interval = ep_cfg->ep_interval;
- chan->in = ep_cfg->ep_addr & 0x80 ? 1 : 0;
-
- chan->waitsem = usb_osal_sem_create(0);
- chan->exclsem = usb_osal_mutex_create();
-
- HAL_HCD_HC_Init(g_usbhost.handle, chidx, ep_cfg->ep_addr, hport->dev_addr, speed, ep_cfg->ep_type, ep_cfg->ep_mps);
-
- g_usbhost.handle->hc[chidx].toggle_in = 0;
- g_usbhost.handle->hc[chidx].toggle_out = 0;
-
- *ep = (usbh_epinfo_t)chidx;
- }
-
- return 0;
-}
-
-int usbh_ep_free(usbh_epinfo_t ep)
-{
- if ((uintptr_t)ep < CONFIG_USBHOST_CHANNELS) {
- usb_synopsys_chan_free((int)ep);
- usb_osal_sem_delete(g_usbhost.chan[(int)ep].waitsem);
- usb_osal_mutex_delete(g_usbhost.chan[(int)ep].exclsem);
- } else {
- struct usb_synopsys_ctrlinfo *ep0 = (struct usb_synopsys_ctrlinfo *)ep;
- usb_synopsys_chan_free(ep0->inndx);
- usb_synopsys_chan_free(ep0->outndx);
- usb_osal_sem_delete(g_usbhost.chan[ep0->inndx].waitsem);
- usb_osal_sem_delete(g_usbhost.chan[ep0->outndx].waitsem);
- usb_osal_mutex_delete(g_usbhost.chan[ep0->outndx].exclsem);
- }
-
- return 0;
-}
-
-int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint8_t *buffer)
-{
- int ret;
- uint32_t retries;
- struct usb_synopsys_chan *chan;
- struct usb_synopsys_ctrlinfo *ep0info = (struct usb_synopsys_ctrlinfo *)ep;
-
- chan = &g_usbhost.chan[ep0info->outndx];
- ret = usb_osal_mutex_take(chan->exclsem);
- if (ret < 0) {
- return ret;
- }
-
- usb_synopsys_chan_waitsetup(chan);
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- ep0info->outndx, /* Pipe index */
- 0, /* Direction : OUT */
- 0, /* EP type */
- USBH_PID_SETUP, /* Type Data */
- (uint8_t *)setup, /* data buffer */
- 8, /* data length */
- 0); /* do ping (HS Only)*/
-
- ret = usb_synopsys_chan_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
- if (ret < 0) {
- goto errout_with_mutex;
- }
-
- if (setup->wLength && buffer) {
- if (setup->bmRequestType & 0x80) {
- chan = &g_usbhost.chan[ep0info->inndx];
- usb_synopsys_chan_waitsetup(chan);
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- ep0info->inndx, /* Pipe index */
- 1, /* Direction : IN */
- 0, /* EP type */
- USBH_PID_DATA, /* Type Data */
- buffer, /* data buffer */
- setup->wLength, /* data length */
- 0); /* do ping (HS Only)*/
-
- ret = usb_synopsys_chan_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
- if (ret < 0) {
- goto errout_with_mutex;
- }
-
- chan = &g_usbhost.chan[ep0info->outndx];
-
- /* For ep0 out,we must retry more */
- for (retries = 0; retries < 10; retries++) {
- usb_synopsys_chan_waitsetup(chan);
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- ep0info->outndx, /* Pipe index */
- 0, /* Direction : OUT */
- 0, /* EP type */
- USBH_PID_DATA, /* Type Data */
- NULL, /* data buffer */
- 0, /* data length */
- 0); /* do ping (HS Only)*/
-
- ret = usb_synopsys_chan_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
- if (ret == -EAGAIN) {
- continue;
- } else if (ret < 0) {
- goto errout_with_mutex;
- } else {
- break;
- }
- }
- if (retries >= CONFIG_CONTROL_RETRY_COUNT) {
- ret = -ETIMEDOUT;
- goto errout_with_mutex;
- }
-
- } else {
- chan = &g_usbhost.chan[ep0info->outndx];
-
- /* For ep0 out,we must retry more */
- for (retries = 0; retries < CONFIG_CONTROL_RETRY_COUNT; retries++) {
- usb_synopsys_chan_waitsetup(chan);
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- ep0info->outndx, /* Pipe index */
- 0, /* Direction : OUT */
- 0, /* EP type */
- USBH_PID_DATA, /* Type Data */
- buffer, /* data buffer */
- setup->wLength, /* data length */
- 0); /* do ping (HS Only)*/
-
- ret = usb_synopsys_chan_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
- if (ret == -EAGAIN) {
- continue;
- } else if (ret < 0) {
- goto errout_with_mutex;
- } else {
- break;
- }
- }
- if (retries >= CONFIG_CONTROL_RETRY_COUNT) {
- ret = -ETIMEDOUT;
- goto errout_with_mutex;
- }
-
- chan = &g_usbhost.chan[ep0info->inndx];
- usb_synopsys_chan_waitsetup(chan);
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- ep0info->inndx, /* Pipe index */
- 1, /* Direction : IN */
- 0, /* EP type */
- USBH_PID_DATA, /* Type Data */
- NULL, /* data buffer */
- 0, /* data length */
- 0); /* do ping (HS Only)*/
-
- ret = usb_synopsys_chan_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
- if (ret < 0) {
- goto errout_with_mutex;
- }
- }
- } else {
- chan = &g_usbhost.chan[ep0info->inndx];
- usb_synopsys_chan_waitsetup(chan);
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- ep0info->inndx, /* Pipe index */
- 1, /* Direction : IN */
- 0, /* EP type */
- USBH_PID_DATA, /* Type Data */
- NULL, /* data buffer */
- 0, /* data length */
- 0); /* do ping (HS Only)*/
-
- ret = usb_synopsys_chan_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
- if (ret < 0) {
- goto errout_with_mutex;
- }
- }
- chan = &g_usbhost.chan[ep0info->outndx];
- usb_osal_mutex_give(chan->exclsem);
- return 0;
-errout_with_mutex:
- chan->waiter = false;
- chan = &g_usbhost.chan[ep0info->outndx];
- usb_osal_mutex_give(chan->exclsem);
- return ret;
-}
-
-int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
- int ret;
- struct usb_synopsys_chan *chan;
- struct usb_synopsys_priv *priv = &g_usbhost;
- uint8_t chidx = (uint8_t)ep;
-
- chan = &priv->chan[chidx];
- ret = usb_osal_mutex_take(chan->exclsem);
- if (ret < 0) {
- return ret;
- }
-
- usb_synopsys_chan_waitsetup(chan);
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- chidx, /* Pipe index */
- g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */
- 2, /* EP type */
- USBH_PID_DATA, /* Type Data */
- buffer, /* data buffer */
- buflen, /* data length */
- 0); /* do ping (HS Only)*/
-
- ret = usb_synopsys_chan_wait(chan, timeout);
- if (ret < 0) {
- goto errout_with_mutex;
- }
-
- usb_osal_mutex_give(chan->exclsem);
- return g_usbhost.handle->hc[chidx].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx) : buflen;
-errout_with_mutex:
- chan->waiter = false;
- usb_osal_mutex_give(chan->exclsem);
- return ret;
-}
-
-int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
- size_t flags;
- uint32_t retries;
- int ret;
- struct usb_synopsys_chan *chan;
- uint8_t chidx = (uint8_t)ep;
-
- chan = &g_usbhost.chan[chidx];
- ret = usb_osal_mutex_take(chan->exclsem);
- if (ret < 0) {
- return ret;
- }
-
- usb_synopsys_chan_waitsetup(chan);
- flags = usb_osal_enter_critical_section();
- chan->transfer_state = TRANSFER_BUSY;
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- chidx, /* Pipe index */
- g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */
- 3, /* EP type */
- USBH_PID_DATA, /* Type Data */
- buffer, /* data buffer */
- buflen, /* data length */
- 0); /* do ping (HS Only)*/
-
- usb_osal_leave_critical_section(flags);
- ret = usb_synopsys_chan_wait(chan, timeout);
- if (ret < 0) {
- goto errout_with_mutex;
- }
-
- usb_osal_mutex_give(chan->exclsem);
- return g_usbhost.handle->hc[chidx].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx) : buflen;
-errout_with_mutex:
- chan->waiter = false;
- usb_osal_mutex_give(chan->exclsem);
- return ret;
-}
-
-int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg)
-{
- int ret;
- struct usb_synopsys_chan *chan;
- struct usb_synopsys_priv *priv = &g_usbhost;
- uint8_t chidx = (uint8_t)ep;
-
- chan = &g_usbhost.chan[chidx];
- ret = usb_osal_mutex_take(chan->exclsem);
- if (ret < 0) {
- return ret;
- }
-
- usb_synopsys_chan_asynchsetup(chan, callback, arg);
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- chidx, /* Pipe index */
- g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */
- 2, /* EP type */
- USBH_PID_DATA, /* Type Data */
- buffer, /* data buffer */
- buflen, /* data length */
- 0); /* do ping (HS Only)*/
-
- usb_osal_mutex_give(chan->exclsem);
-
- return ret;
-}
-
-int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg)
-{
- int ret;
- size_t flags;
- struct usb_synopsys_chan *chan;
- struct usb_synopsys_priv *priv = &g_usbhost;
- uint8_t chidx = (uint8_t)ep;
-
- chan = &priv->chan[chidx];
- ret = usb_osal_mutex_take(chan->exclsem);
- if (ret < 0) {
- return ret;
- }
-
- usb_synopsys_chan_asynchsetup(chan, callback, arg);
- flags = usb_osal_enter_critical_section();
- chan->transfer_state = TRANSFER_BUSY;
-
- ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- chidx, /* Pipe index */
- g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */
- 3, /* EP type */
- USBH_PID_DATA, /* Type Data */
- buffer, /* data buffer */
- buflen, /* data length */
- 0); /* do ping (HS Only)*/
-
- usb_osal_leave_critical_section(flags);
- usb_osal_mutex_give(chan->exclsem);
-
- return ret;
-}
-
-int usb_ep_cancel(usbh_epinfo_t ep)
-{
- int ret;
- size_t flags;
- struct usb_synopsys_chan *chan;
- struct usb_synopsys_priv *priv = &g_usbhost;
-#ifdef CONFIG_USBHOST_ASYNCH
- usbh_asynch_callback_t callback;
- void *arg;
-#endif
-
- uint8_t chidx = (uint8_t)ep;
-
- chan = &priv->chan[chidx];
-
- flags = usb_osal_enter_critical_section();
-
- chan->result = -ESHUTDOWN;
-#ifdef CONFIG_USBHOST_ASYNCH
- /* Extract the callback information */
- callback = chan->callback;
- arg = chan->arg;
- chan->callback = NULL;
- chan->arg = NULL;
- chan->xfrd = 0;
-#endif
- usb_osal_leave_critical_section(flags);
-
- /* Is there a thread waiting for this transfer to complete? */
-
- if (chan->waiter) {
- /* Wake'em up! */
- chan->waiter = false;
- usb_osal_sem_give(chan->waitsem);
- }
-#ifdef CONFIG_USBHOST_ASYNCH
- /* No.. is an asynchronous callback expected when the transfer completes? */
- else if (callback) {
- /* Then perform the callback */
- callback(arg, -ESHUTDOWN);
- }
-#endif
- return 0;
-}
-
-void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
-{
- if (!g_usbhost.connected) {
- g_usbhost.connected = true;
- extern void usbh_event_notify_handler(uint8_t event, uint8_t rhport);
- usbh_event_notify_handler(USBH_EVENT_CONNECTED, 1);
- }
-}
-
-/**
- * @brief SOF callback.
- * @param hhcd: HCD handle
- * @retval None
- */
-void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
-{
- if (g_usbhost.connected) {
- g_usbhost.connected = false;
- usb_synopsys_chan_freeall();
-
- for (uint8_t chnum = 0; chnum < CONFIG_USBHOST_CHANNELS; chnum++) {
- {
- if (g_usbhost.chan[chnum].waiter) {
- /* Wake'em up! */
- g_usbhost.chan[chnum].waiter = false;
- usb_osal_sem_give(g_usbhost.chan[chnum].waitsem);
- }
- }
-
- usbh_event_notify_handler(USBH_EVENT_DISCONNECTED, 1);
- }
- }
-}
-
-void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
-{
- struct usb_synopsys_chan *chan;
- struct usb_synopsys_priv *priv = &g_usbhost;
-
- chan = &priv->chan[chnum];
-
- if (urb_state == URB_NOTREADY) {
- chan->result = -EAGAIN;
- } else if (urb_state == URB_STALL) {
- chan->result = -EPERM;
- } else if (urb_state == URB_ERROR) {
- chan->result = -EIO;
- } else if (urb_state == URB_DONE) {
- chan->transfer_state = TRANSFER_IDLE;
- chan->result = 0;
- }
- chan->in = g_usbhost.handle->hc[chnum].ep_is_in;
- chan->xfrd += g_usbhost.handle->hc[chnum].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chnum) : g_usbhost.handle->hc[chnum].xfer_len;
-
- if (g_usbhost.handle->hc[chnum].ep_type == 0x00 && (urb_state == URB_NOTREADY) && g_usbhost.handle->hc[chnum].ep_is_in) {
- return;
- }
- if ((g_usbhost.handle->hc[chnum].ep_type == 0x02) && (urb_state == URB_NOTREADY)) {
- return;
- }
-
- usb_synopsys_chan_wakeup(chan);
-}
-
-void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
-{
- g_usbhost.sof_timer++;
- for (uint8_t chnum = 2; chnum < CONFIG_USBHOST_CHANNELS; chnum++) {
- if (g_usbhost.handle->hc[chnum].ep_type == 0x01 || g_usbhost.handle->hc[chnum].ep_type == 0x03) {
- if ((g_usbhost.chan[chnum].transfer_state == TRANSFER_BUSY) &&
- ((g_usbhost.sof_timer % g_usbhost.chan[chnum].interval) == 0)) {
- HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
- chnum, /* Pipe index */
- g_usbhost.handle->hc[chnum].ep_is_in ? 1 : 0, /* Direction : IN */
- g_usbhost.handle->hc[chnum].ep_type, /* EP type */
- USBH_PID_DATA, /* Type Data */
- g_usbhost.handle->hc[chnum].xfer_buff, /* data buffer */
- g_usbhost.handle->hc[chnum].xfer_len, /* data length */
- 0); /* do ping (HS Only)*/
- }
- }
- }
-}
-
-void USBH_IRQHandler(void)
-{
- /* USER CODE BEGIN OTG_HS_IRQn 0 */
-
- /* USER CODE END OTG_HS_IRQn 0 */
- HAL_HCD_IRQHandler(g_usbhost.handle);
- /* USER CODE BEGIN OTG_HS_IRQn 1 */
-
- /* USER CODE END OTG_HS_IRQn 1 */
-}
-
-void HAL_Delay(uint32_t Delay)
-{
- usb_osal_msleep(Delay);
-}