diff options
| author | sakumisu <[email protected]> | 2021-11-18 22:04:26 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2021-11-18 22:04:26 +0800 |
| commit | d29f615fd1e8d3a98161622588981b6111f47330 (patch) | |
| tree | ae65a9014ec0cc9d00d9babad193a4c52905a1cc | |
| parent | 8aea7344ca0902ae7b06533861854c23b070c6f4 (diff) | |
add stm32 usb_dc with reg
| -rw-r--r-- | demo/stm32f103c8t6/Core/Src/main.c | 49 | ||||
| -rw-r--r-- | demo/stm32f103c8t6/Core/Src/stm32f1xx_it.c | 20 | ||||
| -rw-r--r-- | demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx | 6 | ||||
| -rw-r--r-- | demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx | 4 | ||||
| -rw-r--r-- | port/stm32/README.md | 7 | ||||
| -rw-r--r-- | port/stm32/usb_dc_hal.c (renamed from port/stm32/usb_dc.c) | 25 | ||||
| -rw-r--r-- | port/stm32/usb_dc_nohal.c | 452 |
7 files changed, 514 insertions, 49 deletions
diff --git a/demo/stm32f103c8t6/Core/Src/main.c b/demo/stm32f103c8t6/Core/Src/main.c index d9879cc2..ff378d53 100644 --- a/demo/stm32f103c8t6/Core/Src/main.c +++ b/demo/stm32f103c8t6/Core/Src/main.c @@ -41,9 +41,9 @@ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ -UART_HandleTypeDef huart1; +//UART_HandleTypeDef huart1; -PCD_HandleTypeDef hpcd_USB_FS; +//PCD_HandleTypeDef hpcd_USB_FS; /* USER CODE BEGIN PV */ @@ -63,7 +63,8 @@ static void MX_USB_PCD_Init(void); int fputc(int ch, FILE *f) { - HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,1000); + while((USART1->SR & USART_SR_TXE) == 0); + USART1->DR = ch; return ch; } @@ -214,7 +215,7 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); - MX_USB_PCD_Init(); + //MX_USB_PCD_Init(); /* USER CODE BEGIN 2 */ usbd_desc_register(cdc_descriptor); @@ -232,7 +233,7 @@ int main(void) while (1) { /* USER CODE END WHILE */ - + /* USER CODE BEGIN 3 */ uint8_t data_buffer[10] = {0x31,0x32,0x33,0x34,0x35,0x31,0x32,0x33,0x34,0x35}; usbd_ep_write(0x81,data_buffer,10,NULL); @@ -324,31 +325,31 @@ static void MX_USART1_UART_Init(void) * @param None * @retval None */ -static void MX_USB_PCD_Init(void) -{ +//static void MX_USB_PCD_Init(void) +//{ - /* USER CODE BEGIN USB_Init 0 */ +// /* USER CODE BEGIN USB_Init 0 */ - /* USER CODE END USB_Init 0 */ +// /* USER CODE END USB_Init 0 */ - /* USER CODE BEGIN USB_Init 1 */ +// /* USER CODE BEGIN USB_Init 1 */ - /* USER CODE END USB_Init 1 */ - hpcd_USB_FS.Instance = USB; - hpcd_USB_FS.Init.dev_endpoints = 8; - hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; - hpcd_USB_FS.Init.low_power_enable = DISABLE; - hpcd_USB_FS.Init.lpm_enable = DISABLE; - hpcd_USB_FS.Init.battery_charging_enable = DISABLE; - if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN USB_Init 2 */ +// /* USER CODE END USB_Init 1 */ +// hpcd_USB_FS.Instance = USB; +// hpcd_USB_FS.Init.dev_endpoints = 8; +// hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; +// hpcd_USB_FS.Init.low_power_enable = DISABLE; +// hpcd_USB_FS.Init.lpm_enable = DISABLE; +// hpcd_USB_FS.Init.battery_charging_enable = DISABLE; +// if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) +// { +// Error_Handler(); +// } +// /* USER CODE BEGIN USB_Init 2 */ - /* USER CODE END USB_Init 2 */ +// /* USER CODE END USB_Init 2 */ -} +//} /** * @brief GPIO Initialization Function diff --git a/demo/stm32f103c8t6/Core/Src/stm32f1xx_it.c b/demo/stm32f103c8t6/Core/Src/stm32f1xx_it.c index 01bd6a6c..2541d10e 100644 --- a/demo/stm32f103c8t6/Core/Src/stm32f1xx_it.c +++ b/demo/stm32f103c8t6/Core/Src/stm32f1xx_it.c @@ -56,7 +56,7 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ -extern PCD_HandleTypeDef hpcd_USB_FS; +//extern PCD_HandleTypeDef hpcd_USB_FS; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -202,16 +202,16 @@ void SysTick_Handler(void) /** * @brief This function handles USB low priority or CAN RX0 interrupts. */ -void USB_LP_CAN1_RX0_IRQHandler(void) -{ - /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */ - - /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */ - HAL_PCD_IRQHandler(&hpcd_USB_FS); - /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */ + void USB_LP_CAN1_RX0_IRQHandler(void) + { + /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */ + extern void USBD_IRQHandler(void); + /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */ + USBD_IRQHandler(); + /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */ - /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */ -} + /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */ + } /* USER CODE BEGIN 1 */ diff --git a/demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx b/demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx index f37fa9c6..cdb81f18 100644 --- a/demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx +++ b/demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx @@ -284,7 +284,7 @@ <Group> <GroupName>Drivers/STM32F1xx_HAL_Driver</GroupName> - <tvExp>0</tvExp> + <tvExp>1</tvExp> <tvExpOptDlg>0</tvExpOptDlg> <cbSel>0</cbSel> <RteFlg>0</RteFlg> @@ -551,8 +551,8 @@ <tvExp>0</tvExp> <tvExpOptDlg>0</tvExpOptDlg> <bDave2>0</bDave2> - <PathWithFileName>..\..\..\port\stm32\usb_dc.c</PathWithFileName> - <FilenameWithoutPath>usb_dc.c</FilenameWithoutPath> + <PathWithFileName>..\..\..\port\stm32\usb_dc_nohal.c</PathWithFileName> + <FilenameWithoutPath>usb_dc_nohal.c</FilenameWithoutPath> <RteFlg>0</RteFlg> <bShared>0</bShared> </File> diff --git a/demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx b/demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx index 93e22351..9a7c5b35 100644 --- a/demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx +++ b/demo/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx @@ -525,9 +525,9 @@ <FilePath>..\..\..\class\cdc\usbd_cdc.c</FilePath> </File> <File> - <FileName>usb_dc.c</FileName> + <FileName>usb_dc_nohal.c</FileName> <FileType>1</FileType> - <FilePath>..\..\..\port\stm32\usb_dc.c</FilePath> + <FilePath>..\..\..\port\stm32\usb_dc_nohal.c</FilePath> </File> </Files> </Group> diff --git a/port/stm32/README.md b/port/stm32/README.md new file mode 100644 index 00000000..de66f44a --- /dev/null +++ b/port/stm32/README.md @@ -0,0 +1,7 @@ +# 基本工程生成 + +- 首先使用 stm32cubemx 使能系统时钟、USB时钟、USB引脚,勾选 USB外设、使能 USB 中断,然后产生基本工程。 +- 如果使用的是 usb_dc_nohal.c,需要注释掉 MX_USB_PCD_Init 函数,USB 中断中调用 USBD_IRQHandler 替代 HAL_PCD_IRQHandler 函数,HAL_PCD_MspInit 函数保留 +- 如果使用的是 usb_dc_hal.c 则上条不需要 +- 推荐使用 nohal 版本,极简代码 + diff --git a/port/stm32/usb_dc.c b/port/stm32/usb_dc_hal.c index b7ea0a35..21e659f4 100644 --- a/port/stm32/usb_dc.c +++ b/port/stm32/usb_dc_hal.c @@ -326,15 +326,25 @@ int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_ if (!data && max_data_len) { return -1; } - if (!max_data_len && (ep == 0x00)) { - /* do nothing*/ - return 0; - } ep_state->read_count = HAL_PCD_EP_GetRxCount(&hpcd_USB_FS, ep); ep_state->read_offset = 0U; read_count = ep_state->read_count; + if (max_data_len == 0) { + /* If no more data in the buffer, start a new read transaction. + * DataOutStageCallback will called on transaction complete. + */ + if (!ep_state->read_count) { + status = HAL_PCD_EP_Receive(&hpcd_USB_FS, ep, + usb_dc_pcd_state.ep_buf[USB_EP_GET_IDX(ep)], + EP_MPS); + if (status != HAL_OK) { + return -2; + } + } + return 0; + } /* When both buffer and max data to read are zero, just ingore reading * and return available data in buffer. Otherwise, return data * previously stored in the buffer. @@ -403,14 +413,9 @@ void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { struct usb_setup_packet *setup = (void *)hpcd_USB_FS.Setup; - struct usb_dc_ep_state *ep_state; - ep_state = usb_dc_stm32_get_ep_state(0x00); - - ep_state->read_count = 8; - ep_state->read_offset = 0U; memcpy(&usb_dc_pcd_state.ep_buf[0], - hpcd_USB_FS.Setup, ep_state->read_count); + hpcd_USB_FS.Setup, 8); usbd_event_notify_handler(USB_EVENT_SETUP_NOTIFY, NULL); if (!(setup->wLength == 0U) && diff --git a/port/stm32/usb_dc_nohal.c b/port/stm32/usb_dc_nohal.c new file mode 100644 index 00000000..5bdacc88 --- /dev/null +++ b/port/stm32/usb_dc_nohal.c @@ -0,0 +1,452 @@ +#include "stm32f1xx_hal.h" //chanage this header for different soc +#include "usbd_core.h" + +#ifndef USB_RAM_SIZE +#define USB_RAM_SIZE 512 +#endif +#ifndef USB_NUM_BIDIR_ENDPOINTS +#define USB_NUM_BIDIR_ENDPOINTS 8 +#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 */ +#ifdef USB + uint16_t ep_pma_buf_len; /** Previously allocated buffer size */ + uint16_t ep_pma_addr; /**ep pmd allocated addr*/ +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif +}; + +/* Driver state */ +struct usb_dc_config_priv { + PCD_TypeDef *Instance; /*!< Register base address */ + __IO uint8_t USB_Address; /*!< USB Address */ + 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 */ +#ifdef USB + uint32_t pma_offset; +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif +} usb_dc_cfg; + +int usb_dc_init(void) +{ + memset(&usb_dc_cfg, 0, sizeof(struct usb_dc_config_priv)); +#ifdef USB + usb_dc_cfg.Instance = USB; + usb_dc_cfg.pma_offset = 64; +#elif defined(USB_OTG_FS) + usb_dc_cfg.Instance = USB_OTG_FS; +#elif defined(USB_OTG_HS) + usb_dc_cfg.Instance = USB_OTG_HS; +#endif + + HAL_PCD_MspInit((PCD_HandleTypeDef *)&usb_dc_cfg); + +#ifdef USB + /* CNTR_FRES = 1 */ + USB->CNTR = (uint16_t)USB_CNTR_FRES; + + /* CNTR_FRES = 0 */ + USB->CNTR = 0U; + + /* Clear pending interrupts */ + USB->ISTR = 0U; + + /*Set Btable Address*/ + USB->BTABLE = BTABLE_ADDRESS; + + USB->DADDR = (uint16_t)USB_DADDR_EF; + + /* Set winterruptmask variable */ + uint32_t winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM; + + /* Set interrupt mask */ + USB->CNTR = (uint16_t)winterruptmask; +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + return 0; +} + +void usb_dc_deinit(void) +{ + HAL_PCD_MspDeInit((PCD_HandleTypeDef *)&usb_dc_cfg); +} + +int usbd_set_address(const uint8_t addr) +{ +#ifdef USB + if (addr == 0U) { + /* set device address and enable function */ + USB->DADDR = (uint16_t)USB_DADDR_EF; + } +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + usb_dc_cfg.USB_Address = addr; + return 0; +} + +int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg) +{ + uint8_t ep; + uint8_t ep_idx; + if (!ep_cfg) { + return -1; + } + + ep = ep_cfg->ep_addr; + ep_idx = USB_EP_GET_IDX(ep); + +#ifdef USB + uint16_t wEpRegVal; + + wEpRegVal = PCD_GET_ENDPOINT(USB, ep_idx) & USB_EP_T_MASK; + /* initialize Endpoint */ + switch (ep_cfg->ep_type) { + case EP_TYPE_CTRL: + wEpRegVal |= USB_EP_CONTROL; + break; + + case EP_TYPE_BULK: + wEpRegVal |= USB_EP_BULK; + break; + + case EP_TYPE_INTR: + wEpRegVal |= USB_EP_INTERRUPT; + break; + + case EP_TYPE_ISOC: + wEpRegVal |= USB_EP_ISOCHRONOUS; + break; + + default: + break; + } + PCD_SET_ENDPOINT(USB, ep_idx, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); + + PCD_SET_EP_ADDRESS(USB, ep_idx, ep_idx); + if (USB_EP_DIR_IS_OUT(ep)) { + 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; + if (usb_dc_cfg.out_ep[ep_idx].ep_mps > usb_dc_cfg.out_ep[ep_idx].ep_pma_buf_len) { + if (usb_dc_cfg.pma_offset + usb_dc_cfg.out_ep[ep_idx].ep_mps >= 512) { + return -1; + } + usb_dc_cfg.out_ep[ep_idx].ep_pma_buf_len = ep_cfg->ep_mps; + usb_dc_cfg.out_ep[ep_idx].ep_pma_addr = usb_dc_cfg.pma_offset; + /*Set the endpoint Receive buffer address */ + PCD_SET_EP_RX_ADDRESS(USB, ep_idx, usb_dc_cfg.pma_offset); + usb_dc_cfg.pma_offset += ep_cfg->ep_mps; + } + /*Set the endpoint Receive buffer counter*/ + PCD_SET_EP_RX_CNT(USB, ep_idx, ep_cfg->ep_mps); + PCD_CLEAR_RX_DTOG(USB, ep_idx); + + /* Configure VALID status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USB, ep_idx, USB_EP_RX_VALID); + } 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; + if (usb_dc_cfg.in_ep[ep_idx].ep_mps > usb_dc_cfg.in_ep[ep_idx].ep_pma_buf_len) { + if (usb_dc_cfg.pma_offset + usb_dc_cfg.in_ep[ep_idx].ep_mps >= USB_RAM_SIZE) { + return -1; + } + usb_dc_cfg.in_ep[ep_idx].ep_pma_buf_len = ep_cfg->ep_mps; + usb_dc_cfg.in_ep[ep_idx].ep_pma_addr = usb_dc_cfg.pma_offset; + /*Set the endpoint Transmit buffer address */ + PCD_SET_EP_TX_ADDRESS(USB, ep_idx, usb_dc_cfg.pma_offset); + usb_dc_cfg.pma_offset += ep_cfg->ep_mps; + } + + PCD_CLEAR_TX_DTOG(USB, ep_idx); + if (ep_cfg->ep_type != EP_TYPE_ISOC) { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USB, ep_idx, USB_EP_TX_NAK); + } else { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USB, ep_idx, USB_EP_TX_DIS); + } + } +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + + return 0; +} +int usbd_ep_close(const uint8_t ep) +{ + uint8_t ep_idx = USB_EP_GET_IDX(ep); + if (USB_EP_DIR_IS_OUT(ep)) { + PCD_CLEAR_RX_DTOG(USB, ep_idx); + + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USB, ep_idx, USB_EP_RX_DIS); + } else { + PCD_CLEAR_TX_DTOG(USB, ep_idx); + + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_TX_STATUS(USB, ep_idx, USB_EP_TX_DIS); + } + 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)) { +#ifdef USB + PCD_SET_EP_RX_STATUS(USB, ep_idx, USB_EP_RX_STALL); +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + } else { +#ifdef USB + PCD_SET_EP_TX_STATUS(USB, ep_idx, USB_EP_TX_STALL); +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + } + 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)) { +#ifdef USB + PCD_CLEAR_TX_DTOG(USB, ep_idx); + + if (usb_dc_cfg.in_ep[ep_idx].ep_type != EP_TYPE_ISOC) { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USB, ep_idx, USB_EP_TX_NAK); + } +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + } else { +#ifdef USB + PCD_CLEAR_RX_DTOG(USB, ep_idx); + /* Configure VALID status for the Endpoint */ + PCD_SET_EP_RX_STATUS(USB, ep_idx, USB_EP_RX_VALID); +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + } + 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); + if (!data && data_len) { + return -1; + } + + if (!data_len) { +#ifdef USB + PCD_SET_EP_TX_CNT(USB, ep_idx, (uint16_t)0); + PCD_SET_EP_TX_STATUS(USB, ep_idx, USB_EP_TX_VALID); +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + 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; + } +#ifdef USB + USB_WritePMA(USB, (uint8_t *)data, usb_dc_cfg.in_ep[ep_idx].ep_pma_addr, (uint16_t)data_len); + PCD_SET_EP_TX_CNT(USB, ep_idx, (uint16_t)data_len); + PCD_SET_EP_TX_STATUS(USB, ep_idx, USB_EP_TX_VALID); +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + 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) +{ + uint32_t read_count; + uint8_t ep_idx = USB_EP_GET_IDX(ep); + if (!data && max_data_len) { + return -1; + } + + if (!max_data_len) { +#ifdef USB + //PCD_SET_EP_RX_CNT(USB, ep_idx, usb_dc_cfg.out_ep[ep_idx].ep_mps); + PCD_SET_EP_RX_STATUS(USB, ep_idx, USB_EP_RX_VALID); +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + return 0; + } +#ifdef USB + read_count = PCD_GET_EP_RX_CNT(USB, ep_idx); + read_count = MIN(read_count, max_data_len); + USB_ReadPMA(USB, (uint8_t *)data, + usb_dc_cfg.out_ep[ep_idx].ep_pma_addr, (uint16_t)read_count); + PCD_SET_EP_RX_STATUS(USB, ep_idx, USB_EP_RX_VALID); +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif + if (read_bytes) { + *read_bytes = read_count; + } + + return 0; +} + +/** + * @brief This function handles PCD interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +void USBD_IRQHandler(void) +{ +#ifdef USB + uint16_t wIstr, wEPVal; + uint8_t epindex; + wIstr = USB->ISTR; + + uint16_t store_ep[8]; + if (wIstr & USB_ISTR_CTR) { + while ((USB->ISTR & USB_ISTR_CTR) != 0U) { + wIstr = USB->ISTR; + + /* extract highest priority endpoint number */ + epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID); + + if (epindex == 0U) { + /* Decode and service control endpoint interrupt */ + + /* DIR bit = origin of the interrupt */ + if ((wIstr & USB_ISTR_DIR) == 0U) { + /* DIR = 0 */ + + /* DIR = 0 => IN int */ + /* DIR = 0 implies that (EP_CTR_TX = 1) always */ + PCD_CLEAR_TX_EP_CTR(USB, PCD_ENDP0); + usbd_event_notify_handler(USB_EVENT_EP0_IN_NOTIFY, NULL); + if ((usb_dc_cfg.USB_Address > 0U) && (PCD_GET_EP_TX_CNT(USB, PCD_ENDP0) == 0U)) { + USB->DADDR = ((uint16_t)usb_dc_cfg.USB_Address | USB_DADDR_EF); + usb_dc_cfg.USB_Address = 0U; + } + } + /* DIR = 1 */ + + /* DIR = 1 & CTR_RX => SETUP or OUT int */ + /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ + + wEPVal = PCD_GET_ENDPOINT(USB, PCD_ENDP0); + + if ((wEPVal & USB_EP_SETUP) != 0U) { + /* SETUP bit kept frozen while CTR_RX = 1 */ + PCD_CLEAR_RX_EP_CTR(USB, PCD_ENDP0); + + /* Process SETUP Packet*/ + usbd_event_notify_handler(USB_EVENT_SETUP_NOTIFY, NULL); + } else if ((wEPVal & USB_EP_CTR_RX) != 0U) { + PCD_CLEAR_RX_EP_CTR(USB, PCD_ENDP0); + /* Process Control Data OUT Packet */ + usbd_event_notify_handler(USB_EVENT_EP0_OUT_NOTIFY, NULL); + } + } else { + /* Decode and service non control endpoints interrupt */ + /* process related endpoint register */ + wEPVal = PCD_GET_ENDPOINT(USB, epindex); + + if ((wEPVal & USB_EP_CTR_RX) != 0U) { + /* clear int flag */ + PCD_CLEAR_RX_EP_CTR(USB, epindex); + usbd_event_notify_handler(USB_EVENT_EP_OUT_NOTIFY, (void *)(epindex & 0x7f)); + } + + if ((wEPVal & USB_EP_CTR_TX) != 0U) { + /* clear int flag */ + PCD_CLEAR_TX_EP_CTR(USB, epindex); + usbd_event_notify_handler(USB_EVENT_EP_IN_NOTIFY, (void *)(epindex | 0x80)); + } + } + } + } + if (wIstr & USB_ISTR_RESET) { + struct usbd_endpoint_cfg ep0_cfg; + /* Configure control EP */ + ep0_cfg.ep_mps = 64; + ep0_cfg.ep_type = USB_DC_EP_CONTROL; + + ep0_cfg.ep_addr = USB_CONTROL_OUT_EP0; + usbd_ep_open(&ep0_cfg); + + ep0_cfg.ep_addr = USB_CONTROL_IN_EP0; + usbd_ep_open(&ep0_cfg); + usbd_event_notify_handler(USB_EVENT_RESET, NULL); + + USB->ISTR &= (uint16_t)(~USB_ISTR_RESET); + } + if (wIstr & USB_ISTR_PMAOVR) { + USB->ISTR &= (uint16_t)(~USB_ISTR_PMAOVR); + } + if (wIstr & USB_ISTR_ERR) { + USB->ISTR &= (uint16_t)(~USB_ISTR_ERR); + } + if (wIstr & USB_ISTR_WKUP) { + USB->CNTR &= (uint16_t) ~(USB_CNTR_LP_MODE); + USB->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP); + + USB->ISTR &= (uint16_t)(~USB_ISTR_WKUP); + } + if (wIstr & USB_ISTR_SUSP) { + /* WA: To Clear Wakeup flag if raised with suspend signal */ + + /* Store Endpoint register */ + for (uint8_t i = 0U; i < 8U; i++) { + store_ep[i] = PCD_GET_ENDPOINT(USB, i); + } + + /* FORCE RESET */ + USB->CNTR |= (uint16_t)(USB_CNTR_FRES); + + /* CLEAR RESET */ + USB->CNTR &= (uint16_t)(~USB_CNTR_FRES); + + /* wait for reset flag in ISTR */ + while ((USB->ISTR & USB_ISTR_RESET) == 0U) { + } + + /* Clear Reset Flag */ + USB->ISTR &= (uint16_t)(~USB_ISTR_RESET); + /* Restore Registre */ + for (uint8_t i = 0U; i < 8U; i++) { + PCD_SET_ENDPOINT(USB, i, store_ep[i]); + } + + /* Force low-power mode in the macrocell */ + USB->CNTR |= (uint16_t)USB_CNTR_FSUSP; + + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + USB->ISTR &= (uint16_t)(~USB_ISTR_SUSP); + + USB->CNTR |= (uint16_t)USB_CNTR_LP_MODE; + } + if (wIstr & USB_ISTR_SOF) { + USB->ISTR &= (uint16_t)(~USB_ISTR_SOF); + } + if (wIstr & USB_ISTR_ESOF) { + USB->ISTR &= (uint16_t)(~USB_ISTR_ESOF); + } +#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) +#endif +}
\ No newline at end of file |
