STM32L4xx_HAL_Driver  1.14.0
PCD Private Functions

Functions

static HAL_StatusTypeDef PCD_WriteEmptyTxFifo (PCD_HandleTypeDef *hpcd, uint32_t epnum)
 Check FIFO for the next packet to be loaded. More...
 
static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int (PCD_HandleTypeDef *hpcd, uint32_t epnum)
 process EP OUT transfer complete interrupt. More...
 
static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int (PCD_HandleTypeDef *hpcd, uint32_t epnum)
 process EP OUT setup packet received interrupt. More...
 
static HAL_StatusTypeDef PCD_EP_ISR_Handler (PCD_HandleTypeDef *hpcd)
 This function handles PCD Endpoint interrupt request. More...
 

Detailed Description

Function Documentation

◆ PCD_EP_ISR_Handler()

static HAL_StatusTypeDef PCD_EP_ISR_Handler ( PCD_HandleTypeDef hpcd)
static

This function handles PCD Endpoint interrupt request.

Parameters
hpcdPCD handle
Return values
HALstatus

Definition at line 2242 of file stm32l4xx_hal_pcd.c.

2243 {
2244  PCD_EPTypeDef *ep;
2245  uint16_t count;
2246  uint16_t wIstr;
2247  uint16_t wEPVal;
2248  uint8_t epindex;
2249 
2250  /* stay in loop while pending interrupts */
2251  while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
2252  {
2253  wIstr = hpcd->Instance->ISTR;
2254  /* extract highest priority endpoint number */
2255  epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
2256 
2257  if (epindex == 0U)
2258  {
2259  /* Decode and service control endpoint interrupt */
2260 
2261  /* DIR bit = origin of the interrupt */
2262  if ((wIstr & USB_ISTR_DIR) == 0U)
2263  {
2264  /* DIR = 0 */
2265 
2266  /* DIR = 0 => IN int */
2267  /* DIR = 0 implies that (EP_CTR_TX = 1) always */
2268  PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2269  ep = &hpcd->IN_ep[0];
2270 
2271  ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
2272  ep->xfer_buff += ep->xfer_count;
2273 
2274  /* TX COMPLETE */
2275 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2276  hpcd->DataInStageCallback(hpcd, 0U);
2277 #else
2278  HAL_PCD_DataInStageCallback(hpcd, 0U);
2279 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2280 
2281  if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
2282  {
2283  hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
2284  hpcd->USB_Address = 0U;
2285  }
2286  }
2287  else
2288  {
2289  /* DIR = 1 */
2290 
2291  /* DIR = 1 & CTR_RX => SETUP or OUT int */
2292  /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
2293  ep = &hpcd->OUT_ep[0];
2294  wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
2295 
2296  if ((wEPVal & USB_EP_SETUP) != 0U)
2297  {
2298  /* Get SETUP Packet*/
2299  ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2300 
2301  USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
2302  ep->pmaadress, (uint16_t)ep->xfer_count);
2303 
2304  /* SETUP bit kept frozen while CTR_RX = 1*/
2305  PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2306 
2307  /* Process SETUP Packet*/
2308 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2309  hpcd->SetupStageCallback(hpcd);
2310 #else
2312 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2313  }
2314 
2315  else if ((wEPVal & USB_EP_CTR_RX) != 0U)
2316  {
2317  PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2318 
2319  /* Get Control Data OUT Packet*/
2320  ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2321 
2322  if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
2323  {
2324  USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
2325  ep->pmaadress, (uint16_t)ep->xfer_count);
2326 
2327  ep->xfer_buff += ep->xfer_count;
2328 
2329  /* Process Control Data OUT Packet*/
2330 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2331  hpcd->DataOutStageCallback(hpcd, 0U);
2332 #else
2333  HAL_PCD_DataOutStageCallback(hpcd, 0U);
2334 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2335  }
2336 
2337  PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
2338  PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
2339  }
2340  }
2341  }
2342  else
2343  {
2344  /* Decode and service non control endpoints interrupt */
2345 
2346  /* process related endpoint register */
2347  wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
2348  if ((wEPVal & USB_EP_CTR_RX) != 0U)
2349  {
2350  /* clear int flag */
2351  PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
2352  ep = &hpcd->OUT_ep[epindex];
2353 
2354  /* OUT double Buffering*/
2355  if (ep->doublebuffer == 0U)
2356  {
2357  count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2358  if (count != 0U)
2359  {
2360  USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
2361  }
2362  }
2363  else
2364  {
2365  if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
2366  {
2367  /*read from endpoint BUF0Addr buffer*/
2368  count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
2369  if (count != 0U)
2370  {
2371  USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
2372  }
2373  }
2374  else
2375  {
2376  /*read from endpoint BUF1Addr buffer*/
2377  count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
2378  if (count != 0U)
2379  {
2380  USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
2381  }
2382  }
2383  /* free EP OUT Buffer */
2384  PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
2385  }
2386  /*multi-packet on the NON control OUT endpoint*/
2387  ep->xfer_count += count;
2388  ep->xfer_buff += count;
2389 
2390  if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
2391  {
2392  /* RX COMPLETE */
2393 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2394  hpcd->DataOutStageCallback(hpcd, ep->num);
2395 #else
2396  HAL_PCD_DataOutStageCallback(hpcd, ep->num);
2397 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2398  }
2399  else
2400  {
2401  (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
2402  }
2403 
2404  } /* if((wEPVal & EP_CTR_RX) */
2405 
2406  if ((wEPVal & USB_EP_CTR_TX) != 0U)
2407  {
2408  ep = &hpcd->IN_ep[epindex];
2409 
2410  /* clear int flag */
2411  PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
2412 
2413  /*multi-packet on the NON control IN endpoint*/
2414  ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
2415  ep->xfer_buff += ep->xfer_count;
2416 
2417  /* Zero Length Packet? */
2418  if (ep->xfer_len == 0U)
2419  {
2420  /* TX COMPLETE */
2421 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2422  hpcd->DataInStageCallback(hpcd, ep->num);
2423 #else
2424  HAL_PCD_DataInStageCallback(hpcd, ep->num);
2425 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2426  }
2427  else
2428  {
2429  (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
2430  }
2431  }
2432  }
2433  }
2434  return HAL_OK;
2435 }
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
Data OUT stage callback.
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
Data IN stage callback.
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
Send an amount of data.
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
Setup stage callback.
return HAL_OK
void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
Copy a buffer from user memory area to packet memory area (PMA)
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
Receive an amount of data.

◆ PCD_EP_OutSetupPacket_int()

static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int ( PCD_HandleTypeDef hpcd,
uint32_t  epnum 
)
static

process EP OUT setup packet received interrupt.

Parameters
hpcdPCD handle
epnumendpoint number
Return values
HALstatus

Definition at line 2211 of file stm32l4xx_hal_pcd.c.

2212 {
2213  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2214  uint32_t USBx_BASE = (uint32_t)USBx;
2215  uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
2216  uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2217 
2218 
2219  if ((gSNPSiD == USB_OTG_CORE_ID_310A) &&
2220  ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2221  {
2222  CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2223  }
2224 
2225  /* Inform the upper layer that a setup packet is available */
2226 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2227  hpcd->SetupStageCallback(hpcd);
2228 #else
2230 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2231 
2232  return HAL_OK;
2233 }
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
Setup stage callback.
return HAL_OK

◆ PCD_EP_OutXfrComplete_int()

static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int ( PCD_HandleTypeDef hpcd,
uint32_t  epnum 
)
static

process EP OUT transfer complete interrupt.

Parameters
hpcdPCD handle
epnumendpoint number
Return values
HALstatus

Definition at line 2164 of file stm32l4xx_hal_pcd.c.

2165 {
2166  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2167  uint32_t USBx_BASE = (uint32_t)USBx;
2168  uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
2169  uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2170 
2171  if (gSNPSiD == USB_OTG_CORE_ID_310A)
2172  {
2173  /* StupPktRcvd = 1 this is a setup packet */
2174  if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
2175  {
2176  CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2177  }
2178  else
2179  {
2180  if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
2181  {
2182  CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2183  }
2184 
2185 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2186  hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2187 #else
2188  HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2189 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2190  }
2191  }
2192  else
2193  {
2194 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2195  hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2196 #else
2197  HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2198 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2199  }
2200 
2201  return HAL_OK;
2202 }
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
Data OUT stage callback.
return HAL_OK

◆ PCD_WriteEmptyTxFifo()

static HAL_StatusTypeDef PCD_WriteEmptyTxFifo ( PCD_HandleTypeDef hpcd,
uint32_t  epnum 
)
static

Check FIFO for the next packet to be loaded.

Parameters
hpcdPCD handle
epnumendpoint number
Return values
HALstatus

Definition at line 2105 of file stm32l4xx_hal_pcd.c.

2106 {
2107  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2108  uint32_t USBx_BASE = (uint32_t)USBx;
2109  USB_OTG_EPTypeDef *ep;
2110  uint32_t len;
2111  uint32_t len32b;
2112  uint32_t fifoemptymsk;
2113 
2114  ep = &hpcd->IN_ep[epnum];
2115 
2116  if (ep->xfer_count > ep->xfer_len)
2117  {
2118  return HAL_ERROR;
2119  }
2120 
2121  len = ep->xfer_len - ep->xfer_count;
2122 
2123  if (len > ep->maxpacket)
2124  {
2125  len = ep->maxpacket;
2126  }
2127 
2128  len32b = (len + 3U) / 4U;
2129 
2130  while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
2131  (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
2132  {
2133  /* Write the FIFO */
2134  len = ep->xfer_len - ep->xfer_count;
2135 
2136  if (len > ep->maxpacket)
2137  {
2138  len = ep->maxpacket;
2139  }
2140  len32b = (len + 3U) / 4U;
2141 
2142  (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len);
2143 
2144  ep->xfer_buff += len;
2145  ep->xfer_count += len;
2146  }
2147 
2148  if (ep->xfer_len <= ep->xfer_count)
2149  {
2150  fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
2151  USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
2152  }
2153 
2154  return HAL_OK;
2155 }
HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
USB_WritePacket : Writes a packet into the Tx FIFO associated with the EP/channel.
return HAL_OK