usbdconfig.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. //*****************************************************************************
  2. //
  3. // usbdconfig.c - High level USB device configuration function.
  4. //
  5. // Copyright (c) 2008-2010 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of AM1808 StarterWare USB Library and reused from revision 6288
  22. // of the Stellaris USB Library.
  23. //
  24. //*****************************************************************************
  25. //#include "hw_memmap.h"
  26. #include "hw_usb.h"
  27. #include "hw_types.h"
  28. #include "debug.h"
  29. #include "usb.h"
  30. #include "usblib.h"
  31. #include "usbdevice.h"
  32. //*****************************************************************************
  33. //
  34. //! \addtogroup device_api
  35. //! @{
  36. //
  37. //*****************************************************************************
  38. //*****************************************************************************
  39. //
  40. // Mask used to preserve various endpoint configuration flags.
  41. //
  42. //*****************************************************************************
  43. #define EP_FLAGS_MASK (USB_EP_MODE_MASK | USB_EP_DEV_IN | \
  44. USB_EP_DEV_OUT)
  45. //*****************************************************************************
  46. //
  47. // Structure used in compiling FIFO size and endpoint properties from a
  48. // configuration descriptor.
  49. //
  50. //*****************************************************************************
  51. typedef struct
  52. {
  53. unsigned int ulSize[2];
  54. unsigned int ulType[2];
  55. }
  56. tUSBEndpointInfo;
  57. //*****************************************************************************
  58. //
  59. // Indices used when accessing the tUSBEndpointInfo structure.
  60. //
  61. //*****************************************************************************
  62. #define EP_INFO_IN 0
  63. #define EP_INFO_OUT 1
  64. //*****************************************************************************
  65. //
  66. // Given a maximum packet size and the user's FIFO scaling requirements,
  67. // determine the flags to use to configure the endpoint FIFO and the number
  68. // of bytes of FIFO space occupied.
  69. //
  70. //*****************************************************************************
  71. static unsigned int
  72. GetEndpointFIFOSize(unsigned int ulMaxPktSize, const tFIFOEntry *psFIFOParams,
  73. unsigned int *pupBytesUsed)
  74. {
  75. unsigned int ulBytes;
  76. unsigned int ulLoop;
  77. unsigned int ulFIFOSize;
  78. //
  79. // A zero multiplier would not be a good thing.
  80. //
  81. ASSERT(psFIFOParams->cMultiplier);
  82. //
  83. // What is the basic size required for a single buffered FIFO entry
  84. // containing the required number of packets?
  85. //
  86. ulBytes = ulMaxPktSize * (unsigned int)psFIFOParams->cMultiplier;
  87. //
  88. // Now we need to find the nearest supported size that accommodates the
  89. // requested size. Step through each of the supported sizes until we
  90. // find one that will do.
  91. //
  92. for(ulLoop = USB_FIFO_SZ_8; ulLoop <= USB_FIFO_SZ_8192; ulLoop++)
  93. {
  94. //
  95. // How many bytes does this FIFO value represent?
  96. //
  97. ulFIFOSize = USB_FIFO_SZ_TO_BYTES(ulLoop);
  98. //
  99. // Is this large enough to satisfy the request?
  100. //
  101. if(ulFIFOSize >= ulBytes)
  102. {
  103. //
  104. // Yes - are we being asked to double-buffer the FIFO for this
  105. // endpoint?
  106. //
  107. if(psFIFOParams->bDoubleBuffer)
  108. {
  109. //
  110. // Yes - FIFO requirement is double in this case.
  111. //
  112. *pupBytesUsed = ulFIFOSize * 2;
  113. return(ulLoop | USB_FIFO_SIZE_DB_FLAG);
  114. }
  115. else
  116. {
  117. //
  118. // No double buffering so just return the size and associated
  119. // flag.
  120. //
  121. *pupBytesUsed = ulFIFOSize;
  122. return(ulLoop);
  123. }
  124. }
  125. }
  126. //
  127. // If we drop out, we can't support the FIFO size requested. Signal a
  128. // problem by returning 0 in the pBytesUsed
  129. //
  130. *pupBytesUsed = 0;
  131. return(USB_FIFO_SZ_8);
  132. }
  133. //*****************************************************************************
  134. //
  135. // Translate a USB endpoint descriptor into the values we need to pass to the
  136. // USBDevEndpointConfigSet() API.
  137. //
  138. //*****************************************************************************
  139. static void
  140. GetEPDescriptorType(tEndpointDescriptor *psEndpoint, unsigned int *pulEPIndex,
  141. unsigned int *pulMaxPktSize, unsigned int *pulFlags)
  142. {
  143. //
  144. // Get the endpoint index.
  145. //
  146. *pulEPIndex = psEndpoint->bEndpointAddress & USB_EP_DESC_NUM_M;
  147. //
  148. // Extract the maximum packet size.
  149. //
  150. *pulMaxPktSize = psEndpoint->wMaxPacketSize & USB_EP_MAX_PACKET_COUNT_M;
  151. //
  152. // Is this an IN or an OUT endpoint?
  153. //
  154. *pulFlags = (psEndpoint->bEndpointAddress & USB_EP_DESC_IN) ?
  155. USB_EP_DEV_IN : USB_EP_DEV_OUT;
  156. //
  157. // Set the endpoint mode.
  158. //
  159. switch(psEndpoint->bmAttributes & USB_EP_ATTR_TYPE_M)
  160. {
  161. case USB_EP_ATTR_CONTROL:
  162. *pulFlags |= USB_EP_MODE_CTRL;
  163. break;
  164. case USB_EP_ATTR_BULK:
  165. *pulFlags |= USB_EP_MODE_BULK;
  166. break;
  167. case USB_EP_ATTR_INT:
  168. *pulFlags |= USB_EP_MODE_INT;
  169. break;
  170. case USB_EP_ATTR_ISOC:
  171. *pulFlags |= USB_EP_MODE_ISOC;
  172. break;
  173. }
  174. }
  175. //*****************************************************************************
  176. //
  177. //! Configure the USB controller appropriately for the device whose config
  178. //! descriptor is passed.
  179. //!
  180. //! \param ulIndex is the zero-based index of the USB controller which is to
  181. //! be configured.
  182. //! \param psConfig is a pointer to the configuration descriptor that the
  183. //! USB controller is to be set up to support.
  184. //! \param psFIFOConfig is a pointer to an array of NUM_USB_EP tFIFOConfig
  185. //! structures detailing how the FIFOs are to be set up for each endpoint
  186. //! used by the configuration.
  187. //!
  188. //! This function may be used to initialize a USB controller to operate as
  189. //! the device whose configuration descriptor is passed. The function
  190. //! enables the USB controller, partitions the FIFO appropriately and
  191. //! configures each endpoint required by the configuration. If the supplied
  192. //! configuration supports multiple alternate settings for any interface,
  193. //! the USB FIFO is set up assuming the worst case use (largest packet size
  194. //! for a given endpoint in any alternate setting using that endpoint) to
  195. //! allow for on-the-fly alternate setting changes later. On return from this
  196. //! function, the USB controller is configured for correct operation of
  197. //! the default configuration of the device described by the descriptor passed.
  198. //!
  199. //! The \e psFIFOConfig parameter allows the caller to provide additional
  200. //! information on USB FIFO configuration that cannot be determined merely
  201. //! by parsing the configuration descriptor. The descriptor provides
  202. //! information on the endpoints that are to be used and the maximum packet
  203. //! size for each but cannot determine whether, for example, double buffering
  204. //! is to be used or how many packets the application wants to be able to
  205. //! store in a given endpoint's FIFO.
  206. //!
  207. //! USBDCDConfig() is an optional call and applications may chose to make
  208. //! direct calls to SysCtlPeripheralEnable(), SysCtlUSBPLLEnable(),
  209. //! USBDevEndpointConfigSet() and USBFIFOConfigSet() instead of using this
  210. //! function. If this function is used, it must be called prior to
  211. //! USBDCDInit() since this call assumes that the low level hardware
  212. //! configuration has been completed before it is made.
  213. //!
  214. //! \return Returns \b true on success or \b false on failure.
  215. //
  216. //*****************************************************************************
  217. tBoolean
  218. USBDeviceConfig(unsigned int ulIndex, const tConfigHeader *psConfig,
  219. const tFIFOConfig *psFIFOConfig)
  220. {
  221. unsigned int ulLoop;
  222. unsigned int ulCount;
  223. unsigned int ulNumInterfaces;
  224. unsigned int ulEpIndex;
  225. unsigned int ulEpType;
  226. unsigned int ulMaxPkt;
  227. unsigned int ulNumEndpoints;
  228. unsigned int ulFlags;
  229. unsigned int ulBytesUsed;
  230. unsigned int ulSection;
  231. tInterfaceDescriptor *psInterface;
  232. tEndpointDescriptor *psEndpoint;
  233. tUSBEndpointInfo psEPInfo[NUM_USB_EP - 1];
  234. //
  235. // We only support 1 USB controller currently.
  236. //
  237. ASSERT(ulIndex == 0);
  238. //
  239. // Catch bad pointers in a debug build.
  240. //
  241. ASSERT(psConfig);
  242. ASSERT(psFIFOConfig);
  243. //
  244. // Clear out our endpoint info.
  245. //
  246. for(ulLoop = 0; ulLoop < (NUM_USB_EP - 1); ulLoop++)
  247. {
  248. psEPInfo[ulLoop].ulSize[EP_INFO_IN] = 0;
  249. psEPInfo[ulLoop].ulType[EP_INFO_IN] = 0;
  250. psEPInfo[ulLoop].ulSize[EP_INFO_OUT] = 0;
  251. psEPInfo[ulLoop].ulType[EP_INFO_OUT] = 0;
  252. }
  253. //
  254. // How many (total) endpoints does this configuration describe?
  255. //
  256. ulNumEndpoints = USBDCDConfigDescGetNum(psConfig,
  257. USB_DTYPE_ENDPOINT);
  258. //
  259. // How many interfaces are included?
  260. //
  261. ulNumInterfaces = USBDCDConfigDescGetNum(psConfig,
  262. USB_DTYPE_INTERFACE);
  263. //
  264. // Look at each endpoint and determine the largest max packet size for
  265. // each endpoint. This will determine how we partition the USB FIFO.
  266. //
  267. for(ulLoop = 0; ulLoop < ulNumEndpoints; ulLoop++)
  268. {
  269. //
  270. // Get a pointer to the endpoint descriptor.
  271. //
  272. psEndpoint = (tEndpointDescriptor *)USBDCDConfigDescGet(
  273. psConfig, USB_DTYPE_ENDPOINT, ulLoop,
  274. &ulSection);
  275. //
  276. // Extract the endpoint number and whether it is an IN or OUT
  277. // endpoint.
  278. //
  279. ulEpIndex = (unsigned int)
  280. psEndpoint->bEndpointAddress & USB_EP_DESC_NUM_M;
  281. ulEpType = (psEndpoint->bEndpointAddress & USB_EP_DESC_IN) ?
  282. EP_INFO_IN : EP_INFO_OUT;
  283. //
  284. // Make sure the endpoint number is valid for our controller. If not,
  285. // return false to indicate an error. Note that 0 is invalid since
  286. // you shouldn't reference endpoint 0 in the config descriptor.
  287. //
  288. if((ulEpIndex >= NUM_USB_EP) || (ulEpIndex == 0))
  289. {
  290. return(false);
  291. }
  292. //
  293. // Does this endpoint have a max packet size requirement larger than
  294. // any previous use we have seen?
  295. //
  296. if(psEndpoint->wMaxPacketSize >
  297. psEPInfo[ulEpIndex - 1].ulSize[ulEpType])
  298. {
  299. //
  300. // Yes - remember the new maximum packet size.
  301. //
  302. psEPInfo[ulEpIndex - 1].ulSize[ulEpType] =
  303. psEndpoint->wMaxPacketSize;
  304. }
  305. }
  306. //
  307. // At this point, we have determined the maximum packet size required
  308. // for each endpoint by any possible alternate setting of any interface
  309. // in this configuration. Now determine the endpoint settings required
  310. // for the interface setting we are actually going to use.
  311. //
  312. for(ulLoop = 0; ulLoop < ulNumInterfaces; ulLoop++)
  313. {
  314. //
  315. // Get the next interface descriptor in the config descriptor.
  316. //
  317. psInterface = USBDCDConfigGetInterface(psConfig,
  318. ulLoop,
  319. USB_DESC_ANY,
  320. &ulSection);
  321. //
  322. // Is this the default interface (bAlternateSetting set to 0)?
  323. //
  324. if(psInterface && (psInterface->bAlternateSetting == 0))
  325. {
  326. //
  327. // This is an interface we are interested in so gather the
  328. // information on its endpoints.
  329. //
  330. ulNumEndpoints = (unsigned int)psInterface->bNumEndpoints;
  331. //
  332. // Walk through each endpoint in this interface and configure
  333. // it appropriately.
  334. //
  335. for(ulCount = 0; ulCount < ulNumEndpoints; ulCount++)
  336. {
  337. //
  338. // Get a pointer to the endpoint descriptor.
  339. //
  340. psEndpoint = USBDCDConfigGetInterfaceEndpoint(psConfig,
  341. psInterface->bInterfaceNumber,
  342. psInterface->bAlternateSetting,
  343. ulCount);
  344. //
  345. // Make sure we got a good pointer.
  346. //
  347. if(psEndpoint)
  348. {
  349. //
  350. // Determine maximum packet size and flags from the
  351. // endpoint descriptor.
  352. //
  353. GetEPDescriptorType(psEndpoint, &ulEpIndex, &ulMaxPkt,
  354. &ulFlags);
  355. //
  356. // Make sure no-one is trying to configure endpoint 0.
  357. //
  358. if(!ulEpIndex)
  359. {
  360. return(false);
  361. }
  362. //
  363. // Include any additional flags that the user wants.
  364. //
  365. if((ulFlags & (USB_EP_DEV_IN | USB_EP_DEV_OUT)) ==
  366. USB_EP_DEV_IN)
  367. {
  368. //
  369. // This is an IN endpoint.
  370. //
  371. ulFlags |= (unsigned int)(
  372. psFIFOConfig->sIn[ulEpIndex - 1].usEPFlags);
  373. psEPInfo[ulEpIndex - 1].ulType[EP_INFO_IN] = ulFlags;
  374. }
  375. else
  376. {
  377. //
  378. // This is an OUT endpoint.
  379. //
  380. ulFlags |= (unsigned int)(
  381. psFIFOConfig->sOut[ulEpIndex - 1].usEPFlags);
  382. psEPInfo[ulEpIndex - 1].ulType[EP_INFO_OUT] = ulFlags;
  383. }
  384. //
  385. // Set the endpoint configuration.
  386. //
  387. USBDevEndpointConfigSet(g_USBInstance[ulIndex].uiBaseAddr,
  388. INDEX_TO_USB_EP(ulEpIndex),
  389. ulMaxPkt, ulFlags);
  390. }
  391. }
  392. }
  393. }
  394. //
  395. // At this point, we have configured all the endpoints that are to be
  396. // used by this configuration's alternate setting 0. Now we go on and
  397. // partition the FIFO based on the maximum packet size information we
  398. // extracted earlier. Endpoint 0 is automatically configured to use the
  399. // first MAX_PACKET_SIZE_EP0 bytes of the FIFO so we start from there.
  400. //
  401. ulCount = MAX_PACKET_SIZE_EP0;
  402. for(ulLoop = 1; ulLoop < NUM_USB_EP; ulLoop++)
  403. {
  404. //
  405. // Configure the IN endpoint at this index if it is referred to
  406. // anywhere.
  407. //
  408. if(psEPInfo[ulLoop - 1].ulSize[EP_INFO_IN])
  409. {
  410. //
  411. // What FIFO size flag do we use for this endpoint?
  412. //
  413. ulMaxPkt = GetEndpointFIFOSize(
  414. psEPInfo[ulLoop - 1].ulSize[EP_INFO_IN],
  415. &(psFIFOConfig->sIn[ulLoop - 1]),
  416. &ulBytesUsed);
  417. //
  418. // If we are told that 0 bytes of FIFO will be used, this implies
  419. // that there is an error in psFIFOConfig or the descriptor
  420. // somewhere so return an error indicator to the caller.
  421. //
  422. if(!ulBytesUsed)
  423. {
  424. return(false);
  425. }
  426. //
  427. // Now actually configure the FIFO for this endpoint.
  428. //
  429. USBFIFOConfigSet(g_USBInstance[ulIndex].uiBaseAddr,
  430. INDEX_TO_USB_EP(ulLoop), ulCount,
  431. ulMaxPkt, USB_EP_DEV_IN);
  432. ulCount += ulBytesUsed;
  433. }
  434. //
  435. // Configure the OUT endpoint at this index.
  436. //
  437. if(psEPInfo[ulLoop - 1].ulSize[EP_INFO_OUT])
  438. {
  439. //
  440. // What FIFO size flag do we use for this endpoint?
  441. //
  442. ulMaxPkt = GetEndpointFIFOSize(
  443. psEPInfo[ulLoop - 1].ulSize[EP_INFO_OUT],
  444. &(psFIFOConfig->sOut[ulLoop - 1]),
  445. &ulBytesUsed);
  446. //
  447. // If we are told that 0 bytes of FIFO will be used, this implies
  448. // that there is an error in psFIFOConfig or the descriptor
  449. // somewhere so return an error indicator to the caller.
  450. //
  451. if(!ulBytesUsed)
  452. {
  453. return(false);
  454. }
  455. //
  456. // Now actually configure the FIFO for this endpoint.
  457. //
  458. USBFIFOConfigSet(g_USBInstance[ulIndex].uiBaseAddr,
  459. INDEX_TO_USB_EP(ulLoop), ulCount,
  460. ulMaxPkt, USB_EP_DEV_OUT);
  461. ulCount += ulBytesUsed;
  462. }
  463. }
  464. //
  465. // If we get to the end, all is well.
  466. //
  467. return(true);
  468. }
  469. //*****************************************************************************
  470. //
  471. //! Configure the affected USB endpoints appropriately for one alternate
  472. //! interface setting.
  473. //!
  474. //! \param ulIndex is the zero-based index of the USB controller which is to
  475. //! be configured.
  476. //! \param psConfig is a pointer to the configuration descriptor that contains
  477. //! the interface whose alternate settings is to be configured.
  478. //! \param ucInterfaceNum is the number of the interface whose alternate
  479. //! setting is to be configured. This number corresponds to the
  480. //! bInterfaceNumber field in the desired interface descriptor.
  481. //! \param ucAlternateSetting is the alternate setting number for the desired
  482. //! interface. This number corresponds to the bAlternateSetting field in the
  483. //! desired interface descriptor.
  484. //!
  485. //! This function may be used to reconfigure the endpoints of an interface
  486. //! for operation in one of the interface's alternate settings. Note that this
  487. //! function assumes that the endpoint FIFO settings will not need to change
  488. //! and only the endpoint mode is changed. This assumption is valid if the
  489. //! USB controller was initialized using a previous call to USBDCDConfig().
  490. //!
  491. //! In reconfiguring the interface endpoints, any additional configuration
  492. //! bits set in the endpoint configuration other than the direction (\b
  493. //! USB_EP_DEV_IN or \b USB_EP_DEV_OUT) and mode (\b USB_EP_MODE_MASK) are
  494. //! preserved.
  495. //!
  496. //! \return Returns \b true on success or \b false on failure.
  497. //
  498. //*****************************************************************************
  499. tBoolean
  500. USBDeviceConfigAlternate(unsigned int ulIndex, const tConfigHeader *psConfig,
  501. unsigned char ucInterfaceNum,
  502. unsigned char ucAlternateSetting)
  503. {
  504. unsigned int ulNumInterfaces;
  505. unsigned int ulNumEndpoints;
  506. unsigned int ulLoop;
  507. unsigned int ulCount;
  508. unsigned int ulMaxPkt;
  509. unsigned int ulOldMaxPkt;
  510. unsigned int ulFlags;
  511. unsigned int ulOldFlags;
  512. unsigned int ulSection;
  513. unsigned int ulEpIndex;
  514. tInterfaceDescriptor *psInterface;
  515. tEndpointDescriptor *psEndpoint;
  516. //
  517. // How many interfaces are included in the descriptor?
  518. //
  519. ulNumInterfaces = USBDCDConfigDescGetNum(psConfig,
  520. USB_DTYPE_INTERFACE);
  521. //
  522. // Find the interface descriptor for the supplied interface and alternate
  523. // setting numbers.
  524. //
  525. for(ulLoop = 0; ulLoop < ulNumInterfaces; ulLoop++)
  526. {
  527. //
  528. // Get the next interface descriptor in the config descriptor.
  529. //
  530. psInterface = USBDCDConfigGetInterface(psConfig, ulLoop, USB_DESC_ANY,
  531. &ulSection);
  532. //
  533. // Is this the default interface (bAlternateSetting set to 0)?
  534. //
  535. if(psInterface &&
  536. (psInterface->bInterfaceNumber == ucInterfaceNum) &&
  537. (psInterface->bAlternateSetting == ucAlternateSetting))
  538. {
  539. //
  540. // This is an interface we are interested in and the descriptor
  541. // representing the alternate setting we want so go ahead and
  542. // reconfigure the endpoints.
  543. //
  544. //
  545. // How many endpoints does this interface have?
  546. //
  547. ulNumEndpoints = (unsigned int)psInterface->bNumEndpoints;
  548. //
  549. // Walk through each endpoint in turn.
  550. //
  551. for(ulCount = 0; ulCount < ulNumEndpoints; ulCount++)
  552. {
  553. //
  554. // Get a pointer to the endpoint descriptor.
  555. //
  556. psEndpoint = USBDCDConfigGetInterfaceEndpoint(psConfig,
  557. psInterface->bInterfaceNumber,
  558. psInterface->bAlternateSetting,
  559. ulCount);
  560. //
  561. // Make sure we got a good pointer.
  562. //
  563. if(psEndpoint)
  564. {
  565. //
  566. // Determine maximum packet size and flags from the
  567. // endpoint descriptor.
  568. //
  569. GetEPDescriptorType(psEndpoint, &ulEpIndex, &ulMaxPkt,
  570. &ulFlags);
  571. //
  572. // Make sure no-one is trying to configure endpoint 0.
  573. //
  574. if(!ulEpIndex)
  575. {
  576. return(false);
  577. }
  578. //
  579. // Get the existing endpoint configuration and mask in the
  580. // new mode and direction bits, leaving everything else
  581. // unchanged.
  582. //
  583. ulOldFlags = ulFlags;
  584. USBDevEndpointConfigGet(g_USBInstance[ulIndex].uiBaseAddr,
  585. INDEX_TO_USB_EP(ulEpIndex),
  586. &ulOldMaxPkt,
  587. &ulOldFlags);
  588. //
  589. // Mask in the previous DMA and auto-set bits.
  590. //
  591. ulFlags = (ulFlags & EP_FLAGS_MASK) |
  592. (ulOldFlags & ~EP_FLAGS_MASK);
  593. //
  594. // Set the endpoint configuration.
  595. //
  596. USBDevEndpointConfigSet(g_USBInstance[ulIndex].uiBaseAddr,
  597. INDEX_TO_USB_EP(ulEpIndex),
  598. ulMaxPkt, ulFlags);
  599. }
  600. }
  601. //
  602. // At this point, we have reconfigured the desired interface so
  603. // return indicating all is well.
  604. //
  605. return(true);
  606. }
  607. }
  608. return(false);
  609. }
  610. //*****************************************************************************
  611. //
  612. // Close the Doxygen group.
  613. //! @}
  614. //
  615. //*****************************************************************************