refactor dwc2 port
This commit is contained in:
22
SConscript
22
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']):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,7 @@
|
||||
<Bp>
|
||||
<Number>0</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>525</LineNumber>
|
||||
<LineNumber>537</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
@@ -166,7 +166,23 @@
|
||||
<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>
|
||||
<Bp>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>383</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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
#endif
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -594,26 +594,21 @@
|
||||
<FileType>1</FileType>
|
||||
<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_hc_dwc2.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usb_workq.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\osal\usb_workq.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usb_hc_synopsys.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\port\synopsys\usb_hc_synopsys.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
|
||||
917
port/dwc2/usb_dc_dwc2.c
Normal file
917
port/dwc2/usb_dc_dwc2.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
#define CLEAR_HC_INT(chnum, __INTERRUPT__) (USBx_HC(chnum)->HCINT = (__INTERRUPT__))
|
||||
#endif
|
||||
1389
port/dwc2/usb_hc_dwc2.c
Normal file
1389
port/dwc2/usb_hc_dwc2.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user