udma.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217
  1. //*****************************************************************************
  2. //
  3. // udma.c - Driver for the micro-DMA controller.
  4. //
  5. // Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions
  10. // are met:
  11. //
  12. // Redistributions of source code must retain the above copyright
  13. // notice, this list of conditions and the following disclaimer.
  14. //
  15. // Redistributions in binary form must reproduce the above copyright
  16. // notice, this list of conditions and the following disclaimer in the
  17. // documentation and/or other materials provided with the
  18. // distribution.
  19. //
  20. // Neither the name of Texas Instruments Incorporated nor the names of
  21. // its contributors may be used to endorse or promote products derived
  22. // from this software without specific prior written permission.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. //*****************************************************************************
  37. //*****************************************************************************
  38. //
  39. //! \addtogroup udma_api
  40. //! @{
  41. //
  42. //*****************************************************************************
  43. #include "types.h"
  44. #include <stdbool.h>
  45. #include <stdint.h>
  46. #include "inc/hw_sysctl.h"
  47. #include "inc/hw_udma.h"
  48. #include "debug.h"
  49. #include "interrupt.h"
  50. #include "udma.h"
  51. //*****************************************************************************
  52. //
  53. //! Initializes the uDMA for use.
  54. //!
  55. //! This function assigns a default peripheral mapping for uDMA channels 20-25.
  56. //! This function must be called in order to prevent multiple channels from
  57. //! being assigned to the same peripheral by moving these channels to an encoding
  58. //! where they are in reserved status.
  59. //!
  60. //! \return None.
  61. //
  62. //*****************************************************************************
  63. void
  64. uDMAInit(void)
  65. {
  66. uDMAChannelAssign(UDMA_CH20_RESERVED7);
  67. uDMAChannelAssign(UDMA_CH21_RESERVED7);
  68. uDMAChannelAssign(UDMA_CH22_RESERVED7);
  69. uDMAChannelAssign(UDMA_CH23_RESERVED7);
  70. uDMAChannelAssign(UDMA_CH24_RESERVED7);
  71. uDMAChannelAssign(UDMA_CH25_RESERVED7);
  72. }
  73. //*****************************************************************************
  74. //
  75. //! Enables the uDMA controller for use.
  76. //!
  77. //! This function enables the uDMA controller. The uDMA controller must be
  78. //! enabled before it can be configured and used.
  79. //!
  80. //! \return None.
  81. //
  82. //*****************************************************************************
  83. void
  84. uDMAEnable(void)
  85. {
  86. //
  87. // Set the master enable bit in the config register.
  88. //
  89. HWREG(UDMA_CFG) = UDMA_CFG_MASTEN;
  90. }
  91. //*****************************************************************************
  92. //
  93. //! Disables the uDMA controller for use.
  94. //!
  95. //! This function disables the uDMA controller. Once disabled, the uDMA
  96. //! controller cannot operate until re-enabled with uDMAEnable().
  97. //!
  98. //! \return None.
  99. //
  100. //*****************************************************************************
  101. void
  102. uDMADisable(void)
  103. {
  104. //
  105. // Clear the master enable bit in the config register.
  106. //
  107. HWREG(UDMA_CFG) = 0;
  108. }
  109. //*****************************************************************************
  110. //
  111. //! Gets the uDMA error status.
  112. //!
  113. //! This function returns the uDMA error status. It should be called from
  114. //! within the uDMA error interrupt handler to determine if a uDMA error
  115. //! occurred.
  116. //!
  117. //! \return Returns non-zero if a uDMA error is pending.
  118. //
  119. //*****************************************************************************
  120. uint32_t
  121. uDMAErrorStatusGet(void)
  122. {
  123. //
  124. // Return the uDMA error status.
  125. //
  126. return (HWREG(UDMA_ERRCLR));
  127. }
  128. //*****************************************************************************
  129. //
  130. //! Clears the uDMA error interrupt.
  131. //!
  132. //! This function clears a pending uDMA error interrupt. This function should
  133. //! be called from within the uDMA error interrupt handler to clear the
  134. //! interrupt.
  135. //!
  136. //! \return None.
  137. //
  138. //*****************************************************************************
  139. void
  140. uDMAErrorStatusClear(void)
  141. {
  142. //
  143. // Clear the uDMA error interrupt.
  144. //
  145. HWREG(UDMA_ERRCLR) = 1;
  146. }
  147. //*****************************************************************************
  148. //
  149. //! Enables a uDMA channel for operation.
  150. //!
  151. //! \param ui32ChannelNum is the channel number to enable.
  152. //!
  153. //! This function enables a specific uDMA channel for use. This function must
  154. //! be used to enable a channel before it can be used to perform a uDMA
  155. //! transfer.
  156. //!
  157. //! When a uDMA transfer is completed, the channel is automatically disabled by
  158. //! the uDMA controller. Therefore, this function should be called prior to
  159. //! starting up any new transfer.
  160. //!
  161. //! \return None.
  162. //
  163. //*****************************************************************************
  164. void
  165. uDMAChannelEnable(uint32_t ui32ChannelNum)
  166. {
  167. //
  168. // Check the arguments.
  169. //
  170. ASSERT((ui32ChannelNum & 0xffff) < 32);
  171. //
  172. // Set the bit for this channel in the enable set register.
  173. //
  174. HWREG(UDMA_ENASET) = 1 << (ui32ChannelNum & 0x1f);
  175. }
  176. //*****************************************************************************
  177. //
  178. //! Disables a uDMA channel for operation.
  179. //!
  180. //! \param ui32ChannelNum is the channel number to disable.
  181. //!
  182. //! This function disables a specific uDMA channel. Once disabled, a channel
  183. //! cannot respond to uDMA transfer requests until re-enabled via
  184. //! uDMAChannelEnable().
  185. //!
  186. //! \return None.
  187. //
  188. //*****************************************************************************
  189. void
  190. uDMAChannelDisable(uint32_t ui32ChannelNum)
  191. {
  192. //
  193. // Check the arguments.
  194. //
  195. ASSERT((ui32ChannelNum & 0xffff) < 32);
  196. //
  197. // Set the bit for this channel in the enable clear register.
  198. //
  199. HWREG(UDMA_ENACLR) = 1 << (ui32ChannelNum & 0x1f);
  200. }
  201. //*****************************************************************************
  202. //
  203. //! Checks if a uDMA channel is enabled for operation.
  204. //!
  205. //! \param ui32ChannelNum is the channel number to check.
  206. //!
  207. //! This function checks to see if a specific uDMA channel is enabled. This
  208. //! function can be used to check the status of a transfer, as the channel is
  209. //! automatically disabled at the end of a transfer.
  210. //!
  211. //! \return Returns \b true if the channel is enabled, \b false if disabled.
  212. //
  213. //*****************************************************************************
  214. bool
  215. uDMAChannelIsEnabled(uint32_t ui32ChannelNum)
  216. {
  217. //
  218. // Check the arguments.
  219. //
  220. ASSERT((ui32ChannelNum & 0xffff) < 32);
  221. //
  222. // AND the specified channel bit with the enable register and return the
  223. // result.
  224. //
  225. return ((HWREG(UDMA_ENASET) & (1 << (ui32ChannelNum & 0x1f))) ? true :
  226. false);
  227. }
  228. //*****************************************************************************
  229. //
  230. //! Sets the base address for the channel control table.
  231. //!
  232. //! \param psControlTable is a pointer to the 1024-byte-aligned base address
  233. //! of the uDMA channel control table.
  234. //!
  235. //! This function configures the base address of the channel control table.
  236. //! This table resides in system memory and holds control information for each
  237. //! uDMA channel. The table must be aligned on a 1024-byte boundary. The base
  238. //! address must be configured before any of the channel functions can be used.
  239. //!
  240. //! The size of the channel control table depends on the number of uDMA
  241. //! channels and the transfer modes that are used. Refer to the technical
  242. //! reference manual and the data sheet for more information about the channel
  243. //! control table.
  244. //!
  245. //! \return None.
  246. //
  247. //*****************************************************************************
  248. void
  249. uDMAControlBaseSet(void *psControlTable)
  250. {
  251. //
  252. // Check the arguments.
  253. //
  254. ASSERT(((uint32_t)psControlTable & ~0x3FF) ==
  255. (uint32_t)psControlTable);
  256. ASSERT((uint32_t)psControlTable >= 0x20000000);
  257. //
  258. // Program the base address into the register.
  259. //
  260. HWREG(UDMA_CTLBASE) = (uint32_t)psControlTable;
  261. }
  262. //*****************************************************************************
  263. //
  264. //! Gets the base address for the channel control table.
  265. //!
  266. //! This function gets the base address of the channel control table. This
  267. //! table resides in system memory and holds control information for each uDMA
  268. //! channel.
  269. //!
  270. //! \return Returns a pointer to the base address of the channel control table.
  271. //
  272. //*****************************************************************************
  273. void *
  274. uDMAControlBaseGet(void)
  275. {
  276. //
  277. // Read the current value of the control base register and return it to
  278. // the caller.
  279. //
  280. return ((void *)HWREG(UDMA_CTLBASE));
  281. }
  282. //*****************************************************************************
  283. //
  284. //! Gets the base address for the channel control table alternate structures.
  285. //!
  286. //! This function gets the base address of the second half of the channel
  287. //! control table that holds the alternate control structures for each channel.
  288. //!
  289. //! \return Returns a pointer to the base address of the second half of the
  290. //! channel control table.
  291. //
  292. //*****************************************************************************
  293. void *
  294. uDMAControlAlternateBaseGet(void)
  295. {
  296. //
  297. // Read the current value of the control base register and return it to
  298. // the caller.
  299. //
  300. return ((void *)HWREG(UDMA_ALTBASE));
  301. }
  302. //*****************************************************************************
  303. //
  304. //! Requests a uDMA channel to start a transfer.
  305. //!
  306. //! \param ui32ChannelNum is the channel number on which to request a uDMA
  307. //! transfer.
  308. //!
  309. //! This function allows software to request a uDMA channel to begin a
  310. //! transfer. This function could be used for performing a memory-to-memory
  311. //! transfer, or if for some reason a transfer needs to be initiated by
  312. //! software instead of the peripheral associated with that channel.
  313. //!
  314. //! \note If the channel is \b UDMA_CHANNEL_SW and interrupts are used, then
  315. //! the completion is signaled on the uDMA dedicated interrupt. If a
  316. //! peripheral channel is used, then the completion is signaled on the
  317. //! peripheral's interrupt.
  318. //!
  319. //! \return None.
  320. //
  321. //*****************************************************************************
  322. void
  323. uDMAChannelRequest(uint32_t ui32ChannelNum)
  324. {
  325. //
  326. // Check the arguments.
  327. //
  328. ASSERT((ui32ChannelNum & 0xffff) < 32);
  329. //
  330. // Set the bit for this channel in the software uDMA request register.
  331. //
  332. HWREG(UDMA_SWREQ) = 1 << (ui32ChannelNum & 0x1f);
  333. }
  334. //*****************************************************************************
  335. //
  336. //! Enables attributes of a uDMA channel.
  337. //!
  338. //! \param ui32ChannelNum is the channel to configure.
  339. //! \param ui32Attr is a combination of attributes for the channel.
  340. //!
  341. //! This function is used to enable attributes of a uDMA channel.
  342. //!
  343. //! The \e ui32Attr parameter is the logical OR of any of the following:
  344. //!
  345. //! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst
  346. //! mode.
  347. //! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure
  348. //! for this channel (it is very unlikely that this flag should be used).
  349. //! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
  350. //! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
  351. //! peripheral for this channel.
  352. //!
  353. //! \return None.
  354. //
  355. //*****************************************************************************
  356. void
  357. uDMAChannelAttributeEnable(uint32_t ui32ChannelNum, uint32_t ui32Attr)
  358. {
  359. //
  360. // Check the arguments.
  361. //
  362. ASSERT((ui32ChannelNum & 0xffff) < 32);
  363. ASSERT((ui32Attr & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
  364. UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) == 0);
  365. //
  366. // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
  367. // passed as the ui32ChannelNum parameter, extract just the channel number
  368. // from this parameter.
  369. //
  370. ui32ChannelNum &= 0x1f;
  371. //
  372. // Set the useburst bit for this channel if set in ui32Config.
  373. //
  374. if (ui32Attr & UDMA_ATTR_USEBURST)
  375. {
  376. HWREG(UDMA_USEBURSTSET) = 1 << ui32ChannelNum;
  377. }
  378. //
  379. // Set the alternate control select bit for this channel,
  380. // if set in ui32Config.
  381. //
  382. if (ui32Attr & UDMA_ATTR_ALTSELECT)
  383. {
  384. HWREG(UDMA_ALTSET) = 1 << ui32ChannelNum;
  385. }
  386. //
  387. // Set the high priority bit for this channel, if set in ui32Config.
  388. //
  389. if (ui32Attr & UDMA_ATTR_HIGH_PRIORITY)
  390. {
  391. HWREG(UDMA_PRIOSET) = 1 << ui32ChannelNum;
  392. }
  393. //
  394. // Set the request mask bit for this channel, if set in ui32Config.
  395. //
  396. if (ui32Attr & UDMA_ATTR_REQMASK)
  397. {
  398. HWREG(UDMA_REQMASKSET) = 1 << ui32ChannelNum;
  399. }
  400. }
  401. //*****************************************************************************
  402. //
  403. //! Disables attributes of a uDMA channel.
  404. //!
  405. //! \param ui32ChannelNum is the channel to configure.
  406. //! \param ui32Attr is a combination of attributes for the channel.
  407. //!
  408. //! This function is used to disable attributes of a uDMA channel.
  409. //!
  410. //! The \e ui32Attr parameter is the logical OR of any of the following:
  411. //!
  412. //! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst
  413. //! mode.
  414. //! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure
  415. //! for this channel.
  416. //! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
  417. //! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
  418. //! peripheral for this channel.
  419. //!
  420. //! \return None.
  421. //
  422. //*****************************************************************************
  423. void
  424. uDMAChannelAttributeDisable(uint32_t ui32ChannelNum, uint32_t ui32Attr)
  425. {
  426. //
  427. // Check the arguments.
  428. //
  429. ASSERT((ui32ChannelNum & 0xffff) < 32);
  430. ASSERT((ui32Attr & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
  431. UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) == 0);
  432. //
  433. // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
  434. // passed as the ui32ChannelNum parameter, extract just the channel number
  435. // from this parameter.
  436. //
  437. ui32ChannelNum &= 0x1f;
  438. //
  439. // Clear the useburst bit for this channel if set in ui32Config.
  440. //
  441. if (ui32Attr & UDMA_ATTR_USEBURST)
  442. {
  443. HWREG(UDMA_USEBURSTCLR) = 1 << ui32ChannelNum;
  444. }
  445. //
  446. // Clear the alternate control select bit for this channel, if set in
  447. // ui32Config.
  448. //
  449. if (ui32Attr & UDMA_ATTR_ALTSELECT)
  450. {
  451. HWREG(UDMA_ALTCLR) = 1 << ui32ChannelNum;
  452. }
  453. //
  454. // Clear the high priority bit for this channel, if set in ui32Config.
  455. //
  456. if (ui32Attr & UDMA_ATTR_HIGH_PRIORITY)
  457. {
  458. HWREG(UDMA_PRIOCLR) = 1 << ui32ChannelNum;
  459. }
  460. //
  461. // Clear the request mask bit for this channel, if set in ui32Config.
  462. //
  463. if (ui32Attr & UDMA_ATTR_REQMASK)
  464. {
  465. HWREG(UDMA_REQMASKCLR) = 1 << ui32ChannelNum;
  466. }
  467. }
  468. //*****************************************************************************
  469. //
  470. //! Gets the enabled attributes of a uDMA channel.
  471. //!
  472. //! \param ui32ChannelNum is the channel to configure.
  473. //!
  474. //! This function returns a combination of flags representing the attributes of
  475. //! the uDMA channel.
  476. //!
  477. //! \return Returns the logical OR of the attributes of the uDMA channel, which
  478. //! can be any of the following:
  479. //! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst
  480. //! mode.
  481. //! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure
  482. //! for this channel.
  483. //! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
  484. //! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
  485. //! peripheral for this channel.
  486. //
  487. //*****************************************************************************
  488. uint32_t
  489. uDMAChannelAttributeGet(uint32_t ui32ChannelNum)
  490. {
  491. uint32_t ui32Attr = 0;
  492. //
  493. // Check the arguments.
  494. //
  495. ASSERT((ui32ChannelNum & 0xffff) < 32);
  496. //
  497. // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
  498. // passed as the ui32ChannelNum parameter, extract just the channel number
  499. // from this parameter.
  500. //
  501. ui32ChannelNum &= 0x1f;
  502. //
  503. // Check to see if useburst bit is set for this channel.
  504. //
  505. if (HWREG(UDMA_USEBURSTSET) & (1 << ui32ChannelNum))
  506. {
  507. ui32Attr |= UDMA_ATTR_USEBURST;
  508. }
  509. //
  510. // Check to see if the alternate control bit is set for this channel.
  511. //
  512. if (HWREG(UDMA_ALTSET) & (1 << ui32ChannelNum))
  513. {
  514. ui32Attr |= UDMA_ATTR_ALTSELECT;
  515. }
  516. //
  517. // Check to see if the high priority bit is set for this channel.
  518. //
  519. if (HWREG(UDMA_PRIOSET) & (1 << ui32ChannelNum))
  520. {
  521. ui32Attr |= UDMA_ATTR_HIGH_PRIORITY;
  522. }
  523. //
  524. // Check to see if the request mask bit is set for this channel.
  525. //
  526. if (HWREG(UDMA_REQMASKSET) & (1 << ui32ChannelNum))
  527. {
  528. ui32Attr |= UDMA_ATTR_REQMASK;
  529. }
  530. //
  531. // Return the configuration flags.
  532. //
  533. return (ui32Attr);
  534. }
  535. //*****************************************************************************
  536. //
  537. //! Sets the control parameters for a uDMA channel control structure.
  538. //!
  539. //! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number
  540. //! with \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
  541. //! \param ui32Control is logical OR of several control values to set the
  542. //! control parameters for the channel.
  543. //!
  544. //! This function is used to set control parameters for a uDMA transfer. These
  545. //! parameters are typically not changed often.
  546. //!
  547. //! The \e ui32ChannelStructIndex parameter should be the logical OR of the
  548. //! channel number with one of \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to
  549. //! choose whether the primary or alternate data structure is used.
  550. //!
  551. //! The \e ui32Control parameter is the logical OR of five values: the data
  552. //! size, the source address increment, the destination address increment, the
  553. //! arbitration size, and the use burst flag. The choices available for each
  554. //! of these values is described below.
  555. //!
  556. //! Choose the data size from one of \b UDMA_SIZE_8, \b UDMA_SIZE_16, or
  557. //! \b UDMA_SIZE_32 to select a data size of 8, 16, or 32 bits.
  558. //!
  559. //! Choose the source address increment from one of \b UDMA_SRC_INC_8,
  560. //! \b UDMA_SRC_INC_16, \b UDMA_SRC_INC_32, or \b UDMA_SRC_INC_NONE to select
  561. //! an address increment of 8-bit bytes, 16-bit half-words, 32-bit words, or
  562. //! to select non-incrementing.
  563. //!
  564. //! Choose the destination address increment from one of \b UDMA_DST_INC_8,
  565. //! \b UDMA_DST_INC_16, \b UDMA_DST_INC_32, or \b UDMA_DST_INC_NONE to select
  566. //! an address increment of 8-bit bytes, 16-bit half-words, 32-bit words, or
  567. //! to select non-incrementing.
  568. //!
  569. //! The arbitration size determines how many items are transferred before
  570. //! the uDMA controller re-arbitrates for the bus. Choose the arbitration size
  571. //! from one of \b UDMA_ARB_1, \b UDMA_ARB_2, \b UDMA_ARB_4, \b UDMA_ARB_8,
  572. //! through \b UDMA_ARB_1024 to select the arbitration size from 1 to 1024
  573. //! items, in powers of 2.
  574. //!
  575. //! The value \b UDMA_NEXT_USEBURST is used to force the channel to only
  576. //! respond to burst requests at the tail end of a scatter-gather transfer.
  577. //!
  578. //! \note The address increment cannot be smaller than the data size.
  579. //!
  580. //! \return None.
  581. //
  582. //*****************************************************************************
  583. void
  584. uDMAChannelControlSet(uint32_t ui32ChannelStructIndex, uint32_t ui32Control)
  585. {
  586. tDMAControlTable *psCtl;
  587. //
  588. // Check the arguments.
  589. //
  590. ASSERT((ui32ChannelStructIndex & 0xffff) < 64);
  591. ASSERT(HWREG(UDMA_CTLBASE) != 0);
  592. //
  593. // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
  594. // passed as the ui32ChannelStructIndex parameter, extract just the channel
  595. // index from this parameter.
  596. //
  597. ui32ChannelStructIndex &= 0x3f;
  598. //
  599. // Get the base address of the control table.
  600. //
  601. psCtl = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
  602. //
  603. // Get the current control word value and mask off the fields to be
  604. // changed, then OR in the new settings.
  605. //
  606. psCtl[ui32ChannelStructIndex].ui32Control =
  607. ((psCtl[ui32ChannelStructIndex].ui32Control &
  608. ~(UDMA_CHCTL_DSTINC_M |
  609. UDMA_CHCTL_DSTSIZE_M |
  610. UDMA_CHCTL_SRCINC_M |
  611. UDMA_CHCTL_SRCSIZE_M |
  612. UDMA_CHCTL_ARBSIZE_M |
  613. UDMA_CHCTL_NXTUSEBURST)) |
  614. ui32Control);
  615. }
  616. //*****************************************************************************
  617. //
  618. //! Sets the transfer parameters for a uDMA channel control structure.
  619. //!
  620. //! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number
  621. //! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
  622. //! \param ui32Mode is the type of uDMA transfer.
  623. //! \param pvSrcAddr is the source address for the transfer.
  624. //! \param pvDstAddr is the destination address for the transfer.
  625. //! \param ui32TransferSize is the number of data items to transfer.
  626. //!
  627. //! This function is used to configure the parameters for a uDMA transfer.
  628. //! These parameters are not typically changed often. The function
  629. //! uDMAChannelControlSet() MUST be called at least once for this channel prior
  630. //! to calling this function.
  631. //!
  632. //! The \e ui32ChannelStructIndex parameter should be the logical OR of the
  633. //! channel number with one of \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to
  634. //! choose whether the primary or alternate data structure is used.
  635. //!
  636. //! The \e ui32Mode parameter should be one of the following values:
  637. //!
  638. //! - \b UDMA_MODE_STOP stops the uDMA transfer. The controller sets the mode
  639. //! to this value at the end of a transfer.
  640. //! - \b UDMA_MODE_BASIC to perform a basic transfer based on request.
  641. //! - \b UDMA_MODE_AUTO to perform a transfer that always completes once
  642. //! started even if the request is removed.
  643. //! - \b UDMA_MODE_PINGPONG to set up a transfer that switches between the
  644. //! primary and alternate control structures for the channel. This mode
  645. //! allows use of ping-pong buffering for uDMA transfers.
  646. //! - \b UDMA_MODE_MEM_SCATTER_GATHER to set up a memory scatter-gather
  647. //! transfer.
  648. //! - \b UDMA_MODE_PER_SCATTER_GATHER to set up a peripheral scatter-gather
  649. //! transfer.
  650. //!
  651. //! The \e pvSrcAddr and \e pvDstAddr parameters are pointers to the first
  652. //! location of the data to be transferred. These addresses should be aligned
  653. //! according to the item size. The compiler takes care of this alignment if
  654. //! the pointers are pointing to storage of the appropriate data type.
  655. //!
  656. //! The \e ui32TransferSize parameter is the number of data items, not the
  657. //! number of bytes.
  658. //!
  659. //! The two scatter-gather modes, memory and peripheral, are actually different
  660. //! depending on whether the primary or alternate control structure is
  661. //! selected. This function looks for the \b UDMA_PRI_SELECT and
  662. //! \b UDMA_ALT_SELECT flag along with the channel number and sets the
  663. //! scatter-gather mode as appropriate for the primary or alternate control
  664. //! structure.
  665. //!
  666. //! The channel must also be enabled using uDMAChannelEnable() after calling
  667. //! this function. The transfer does not begin until the channel has been
  668. //! configured and enabled. Note that the channel is automatically disabled
  669. //! after the transfer is completed, meaning that uDMAChannelEnable() must be
  670. //! called again after setting up the next transfer.
  671. //!
  672. //! \note Great care must be taken to not modify a channel control structure
  673. //! that is in use or else the results are unpredictable, including the
  674. //! possibility of undesired data transfers to or from memory or peripherals.
  675. //! For BASIC and AUTO modes, it is safe to make changes when the channel is
  676. //! disabled, or the uDMAChannelModeGet() returns \b UDMA_MODE_STOP. For
  677. //! PINGPONG or one of the SCATTER_GATHER modes, it is safe to modify the
  678. //! primary or alternate control structure only when the other is being used.
  679. //! The uDMAChannelModeGet() function returns \b UDMA_MODE_STOP when a
  680. //! channel control structure is inactive and safe to modify.
  681. //!
  682. //! \return None.
  683. //
  684. //*****************************************************************************
  685. void
  686. uDMAChannelTransferSet(uint32_t ui32ChannelStructIndex, uint32_t ui32Mode,
  687. void *pvSrcAddr, void *pvDstAddr,
  688. uint32_t ui32TransferSize)
  689. {
  690. tDMAControlTable *psControlTable;
  691. uint32_t ui32Control;
  692. uint32_t ui32Inc;
  693. uint32_t ui32BufferBytes;
  694. //
  695. // Check the arguments.
  696. //
  697. ASSERT((ui32ChannelStructIndex & 0xffff) < 64);
  698. ASSERT(HWREG(UDMA_CTLBASE) != 0);
  699. ASSERT(ui32Mode <= UDMA_MODE_PER_SCATTER_GATHER);
  700. ASSERT((uint32_t)pvSrcAddr >= 0x20000000);
  701. ASSERT((uint32_t)pvDstAddr >= 0x20000000);
  702. ASSERT((ui32TransferSize != 0) && (ui32TransferSize <= 1024));
  703. //
  704. // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
  705. // passed as the ui32ChannelStructIndex parameter, extract just the channel
  706. // index from this parameter.
  707. //
  708. ui32ChannelStructIndex &= 0x3f;
  709. //
  710. // Get the base address of the control table.
  711. //
  712. psControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
  713. //
  714. // Get the current control word value and mask off the mode and size
  715. // fields.
  716. //
  717. ui32Control = (psControlTable[ui32ChannelStructIndex].ui32Control &
  718. ~(UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));
  719. //
  720. // Adjust the mode if the alt control structure is selected.
  721. //
  722. if (ui32ChannelStructIndex & UDMA_ALT_SELECT)
  723. {
  724. if ((ui32Mode == UDMA_MODE_MEM_SCATTER_GATHER) ||
  725. (ui32Mode == UDMA_MODE_PER_SCATTER_GATHER))
  726. {
  727. ui32Mode |= UDMA_MODE_ALT_SELECT;
  728. }
  729. }
  730. //
  731. // Set the transfer size and mode in the control word (but don't write the
  732. // control word yet as it could kick off a transfer).
  733. //
  734. ui32Control |= ui32Mode | ((ui32TransferSize - 1) << 4);
  735. //
  736. // Get the address increment value for the source, from the control word.
  737. //
  738. ui32Inc = (ui32Control & UDMA_CHCTL_SRCINC_M);
  739. //
  740. // Compute the ending source address of the transfer. If the source
  741. // increment is set to none, then the ending address is the same as the
  742. // beginning.
  743. //
  744. if (ui32Inc != UDMA_SRC_INC_NONE)
  745. {
  746. ui32Inc = ui32Inc >> 26;
  747. ui32BufferBytes = ui32TransferSize << ui32Inc;
  748. pvSrcAddr = (void *)((uint32_t)pvSrcAddr + ui32BufferBytes - 1);
  749. }
  750. //
  751. // Load the source ending address into the control block.
  752. //
  753. psControlTable[ui32ChannelStructIndex].pvSrcEndAddr = pvSrcAddr;
  754. //
  755. // Get the address increment value for the destination, from the control
  756. // word.
  757. //
  758. ui32Inc = ui32Control & UDMA_CHCTL_DSTINC_M;
  759. //
  760. // Compute the ending destination address of the transfer. If the
  761. // destination increment is set to none, then the ending address is the
  762. // same as the beginning.
  763. //
  764. if (ui32Inc != UDMA_DST_INC_NONE)
  765. {
  766. //
  767. // There is a special case if this is setting up a scatter-gather
  768. // transfer. The destination pointer must point to the end of
  769. // the alternate structure for this channel instead of calculating
  770. // the end of the buffer in the normal way.
  771. //
  772. if ((ui32Mode == UDMA_MODE_MEM_SCATTER_GATHER) ||
  773. (ui32Mode == UDMA_MODE_PER_SCATTER_GATHER))
  774. {
  775. pvDstAddr =
  776. (void *)&psControlTable[ui32ChannelStructIndex |
  777. UDMA_ALT_SELECT].ui32Spare;
  778. }
  779. //
  780. // Not a scatter-gather transfer, calculate end pointer normally.
  781. //
  782. else
  783. {
  784. ui32Inc = ui32Inc >> 30;
  785. ui32BufferBytes = ui32TransferSize << ui32Inc;
  786. pvDstAddr = (void *)((uint32_t)pvDstAddr + ui32BufferBytes - 1);
  787. }
  788. }
  789. //
  790. // Load the destination ending address into the control block.
  791. //
  792. psControlTable[ui32ChannelStructIndex].pvDstEndAddr = pvDstAddr;
  793. //
  794. // Write the new control word value.
  795. //
  796. psControlTable[ui32ChannelStructIndex].ui32Control = ui32Control;
  797. }
  798. //*****************************************************************************
  799. //
  800. //! Configures a uDMA channel for scatter-gather mode.
  801. //!
  802. //! \param ui32ChannelNum is the uDMA channel number.
  803. //! \param ui32TaskCount is the number of scatter-gather tasks to execute.
  804. //! \param pvTaskList is a pointer to the beginning of the scatter-gather
  805. //! task list.
  806. //! \param ui32IsPeriphSG is a flag to indicate it is a peripheral
  807. //! scatter-gather transfer (else it is memory scatter-gather transfer)
  808. //!
  809. //! This function is used to configure a channel for scatter-gather mode.
  810. //! The caller must have already set up a task list and must pass a pointer to
  811. //! the start of the task list as the \e pvTaskList parameter. The
  812. //! \e ui32TaskCount parameter is the count of tasks in the task list, not the
  813. //! size of the task list. The flag \e bIsPeriphSG should be used to indicate
  814. //! if scatter-gather should be configured for peripheral or memory
  815. //! operation.
  816. //!
  817. //! \sa uDMATaskStructEntry
  818. //!
  819. //! \return None.
  820. //
  821. //*****************************************************************************
  822. void
  823. uDMAChannelScatterGatherSet(uint32_t ui32ChannelNum, uint32_t ui32TaskCount,
  824. void *pvTaskList, uint32_t ui32IsPeriphSG)
  825. {
  826. tDMAControlTable *psControlTable;
  827. tDMAControlTable *psTaskTable;
  828. //
  829. // Check the parameters
  830. //
  831. ASSERT((ui32ChannelNum & 0xffff) < 32);
  832. ASSERT(HWREG(UDMA_CTLBASE) != 0);
  833. ASSERT(pvTaskList != 0);
  834. ASSERT(ui32TaskCount <= 1024);
  835. ASSERT(ui32TaskCount != 0);
  836. //
  837. // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
  838. // passed as the ui32ChannelNum parameter, extract just the channel number
  839. // from this parameter.
  840. //
  841. ui32ChannelNum &= 0x1f;
  842. //
  843. // Get the base address of the control table.
  844. //
  845. psControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
  846. //
  847. // Get a handy pointer to the task list
  848. //
  849. psTaskTable = (tDMAControlTable *)pvTaskList;
  850. //
  851. // Compute the ending address for the source pointer. This address is the
  852. // last element of the last task in the task table
  853. //
  854. psControlTable[ui32ChannelNum].pvSrcEndAddr =
  855. &psTaskTable[ui32TaskCount - 1].ui32Spare;
  856. //
  857. // Compute the ending address for the destination pointer. This address
  858. // is the end of the alternate structure for this channel.
  859. //
  860. psControlTable[ui32ChannelNum].pvDstEndAddr =
  861. &psControlTable[ui32ChannelNum | UDMA_ALT_SELECT].ui32Spare;
  862. //
  863. // Compute the control word. Most configurable items are fixed for
  864. // scatter-gather. Item and increment sizes are all 32-bit and arb
  865. // size must be 4. The count is the number of items in the task list
  866. // times 4 (4 words per task).
  867. //
  868. psControlTable[ui32ChannelNum].ui32Control =
  869. (UDMA_CHCTL_DSTINC_32 | UDMA_CHCTL_DSTSIZE_32 |
  870. UDMA_CHCTL_SRCINC_32 | UDMA_CHCTL_SRCSIZE_32 |
  871. UDMA_CHCTL_ARBSIZE_4 |
  872. (((ui32TaskCount * 4) - 1) << UDMA_CHCTL_XFERSIZE_S) |
  873. (ui32IsPeriphSG ? UDMA_CHCTL_XFERMODE_PER_SG :
  874. UDMA_CHCTL_XFERMODE_MEM_SG));
  875. //
  876. // Scatter-gather operations can leave the alt bit set. So if doing
  877. // back to back scatter-gather transfers, the second attempt may not
  878. // work correctly because the alt bit is set. Therefore, clear the
  879. // alt bit here to ensure that it is always cleared before a new SG
  880. // transfer is started.
  881. //
  882. HWREG(UDMA_ALTCLR) = 1 << ui32ChannelNum;
  883. }
  884. //*****************************************************************************
  885. //
  886. //! Gets the current transfer size for a uDMA channel control structure.
  887. //!
  888. //! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number
  889. //! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
  890. //!
  891. //! This function is used to get the uDMA transfer size for a channel. The
  892. //! transfer size is the number of items to transfer, where the size of an item
  893. //! might be 8, 16, or 32 bits. If a partial transfer has already occurred,
  894. //! then the number of remaining items is returned. If the transfer is
  895. //! complete, then 0 is returned.
  896. //!
  897. //! \return Returns the number of items remaining to transfer.
  898. //
  899. //*****************************************************************************
  900. uint32_t
  901. uDMAChannelSizeGet(uint32_t ui32ChannelStructIndex)
  902. {
  903. tDMAControlTable *psControlTable;
  904. uint32_t ui32Control;
  905. //
  906. // Check the arguments.
  907. //
  908. ASSERT((ui32ChannelStructIndex & 0xffff) < 64);
  909. ASSERT(HWREG(UDMA_CTLBASE) != 0);
  910. //
  911. // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
  912. // passed as the ui32ChannelStructIndex parameter, extract just the channel
  913. // index from this parameter.
  914. //
  915. ui32ChannelStructIndex &= 0x3f;
  916. //
  917. // Get the base address of the control table.
  918. //
  919. psControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
  920. //
  921. // Get the current control word value and mask off all but the size field
  922. // and the mode field.
  923. //
  924. ui32Control = (psControlTable[ui32ChannelStructIndex].ui32Control &
  925. (UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));
  926. //
  927. // If the size field and mode field are 0 then the transfer is finished
  928. // and there are no more items to transfer
  929. //
  930. if (ui32Control == 0)
  931. {
  932. return (0);
  933. }
  934. //
  935. // Otherwise, if either the size field or more field is non-zero, then
  936. // not all the items have been transferred.
  937. //
  938. else
  939. {
  940. //
  941. // Shift the size field and add one, then return to user.
  942. //
  943. return ((ui32Control >> 4) + 1);
  944. }
  945. }
  946. //*****************************************************************************
  947. //
  948. //! Gets the transfer mode for a uDMA channel control structure.
  949. //!
  950. //! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number
  951. //! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
  952. //!
  953. //! This function is used to get the transfer mode for the uDMA channel and
  954. //! to query the status of a transfer on a channel. When the transfer is
  955. //! complete the mode is \b UDMA_MODE_STOP.
  956. //!
  957. //! \return Returns the transfer mode of the specified channel and control
  958. //! structure, which is one of the following values: \b UDMA_MODE_STOP,
  959. //! \b UDMA_MODE_BASIC, \b UDMA_MODE_AUTO, \b UDMA_MODE_PINGPONG,
  960. //! \b UDMA_MODE_MEM_SCATTER_GATHER, or \b UDMA_MODE_PER_SCATTER_GATHER.
  961. //
  962. //*****************************************************************************
  963. uint32_t
  964. uDMAChannelModeGet(uint32_t ui32ChannelStructIndex)
  965. {
  966. tDMAControlTable *psControlTable;
  967. uint32_t ui32Control;
  968. //
  969. // Check the arguments.
  970. //
  971. ASSERT((ui32ChannelStructIndex & 0xffff) < 64);
  972. ASSERT(HWREG(UDMA_CTLBASE) != 0);
  973. //
  974. // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
  975. // passed as the ui32ChannelStructIndex parameter, extract just the channel
  976. // index from this parameter.
  977. //
  978. ui32ChannelStructIndex &= 0x3f;
  979. //
  980. // Get the base address of the control table.
  981. //
  982. psControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
  983. //
  984. // Get the current control word value and mask off all but the mode field.
  985. //
  986. ui32Control = (psControlTable[ui32ChannelStructIndex].ui32Control &
  987. UDMA_CHCTL_XFERMODE_M);
  988. //
  989. // Check if scatter/gather mode, and if so, mask off the alt bit.
  990. //
  991. if (((ui32Control & ~UDMA_MODE_ALT_SELECT) ==
  992. UDMA_MODE_MEM_SCATTER_GATHER) ||
  993. ((ui32Control & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_PER_SCATTER_GATHER))
  994. {
  995. ui32Control &= ~UDMA_MODE_ALT_SELECT;
  996. }
  997. //
  998. // Return the mode to the caller.
  999. //
  1000. return (ui32Control);
  1001. }
  1002. //*****************************************************************************
  1003. //
  1004. //! Registers an interrupt handler for the uDMA controller.
  1005. //!
  1006. //! \param ui32IntChannel identifies which uDMA interrupt is to be registered.
  1007. //! \param pfnHandler is a pointer to the function to be called when the
  1008. //! interrupt is activated.
  1009. //!
  1010. //! This function registers and enables the handler to be called when the uDMA
  1011. //! controller generates an interrupt. The \e ui32IntChannel parameter should
  1012. //! be one of the following:
  1013. //!
  1014. //! - \b INT_UDMA to register an interrupt handler to process interrupts
  1015. //! from the uDMA software channel (UDMA_CHANNEL_SW)
  1016. //! - \b INT_UDMAERR to register an interrupt handler to process uDMA error
  1017. //! interrupts
  1018. //!
  1019. //! \sa IntRegister() for important information about registering interrupt
  1020. //! handlers.
  1021. //!
  1022. //! \note The interrupt handler for the uDMA is for transfer completion when
  1023. //! the channel UDMA_CHANNEL_SW is used and for error interrupts. The
  1024. //! interrupts for each peripheral channel are handled through the individual
  1025. //! peripheral interrupt handlers.
  1026. //!
  1027. //! \return None.
  1028. //
  1029. //*****************************************************************************
  1030. void
  1031. uDMAIntRegister(uint32_t ui32IntChannel, void (*pfnHandler)(void))
  1032. {
  1033. //
  1034. // Check the arguments.
  1035. //
  1036. ASSERT(pfnHandler);
  1037. //
  1038. // Register the interrupt handler.
  1039. //
  1040. IntRegister(ui32IntChannel, pfnHandler);
  1041. //
  1042. // Enable the memory management fault.
  1043. //
  1044. IntEnable(ui32IntChannel);
  1045. }
  1046. //*****************************************************************************
  1047. //
  1048. //! Unregisters an interrupt handler for the uDMA controller.
  1049. //!
  1050. //! \param ui32IntChannel identifies which uDMA interrupt to unregister.
  1051. //!
  1052. //! This function disables and unregisters the handler to be called for the
  1053. //! specified uDMA interrupt. The \e ui32IntChannel parameter should be one of
  1054. //! \b INT_UDMA or \b INT_UDMAERR as documented for the function
  1055. //! uDMAIntRegister().
  1056. //!
  1057. //! \sa IntRegister() for important information about registering interrupt
  1058. //! handlers.
  1059. //!
  1060. //! \return None.
  1061. //
  1062. //*****************************************************************************
  1063. void
  1064. uDMAIntUnregister(uint32_t ui32IntChannel)
  1065. {
  1066. //
  1067. // Disable the interrupt.
  1068. //
  1069. IntDisable(ui32IntChannel);
  1070. //
  1071. // Unregister the interrupt handler.
  1072. //
  1073. IntUnregister(ui32IntChannel);
  1074. }
  1075. //*****************************************************************************
  1076. //
  1077. //! Assigns a peripheral mapping for a uDMA channel.
  1078. //!
  1079. //! \param ui32Mapping is a macro specifying the peripheral assignment for
  1080. //! a channel.
  1081. //!
  1082. //! This function assigns a peripheral mapping to a uDMA channel. It is
  1083. //! used to select which peripheral is used for a uDMA channel. The parameter
  1084. //! \e ui32Mapping should be one of the macros named \b UDMA_CHn_tttt from the
  1085. //! header file \e udma.h. For example, to assign uDMA channel 0 to the
  1086. //! UART2 RX channel, the parameter should be the macro \b UDMA_CH0_UART2RX.
  1087. //!
  1088. //! Please consult the data sheet for a table showing all the possible
  1089. //! peripheral assignments for the uDMA channels.
  1090. //!
  1091. //! \return None.
  1092. //
  1093. //*****************************************************************************
  1094. void
  1095. uDMAChannelAssign(uint32_t ui32Mapping)
  1096. {
  1097. uint32_t ui32MapReg;
  1098. uint_fast8_t ui8MapShift;
  1099. uint_fast8_t ui8ChannelNum;
  1100. //
  1101. // Check the parameters
  1102. //
  1103. ASSERT((ui32Mapping & 0xffffff00) < 0x00090000);
  1104. //
  1105. // Extract the channel number and map encoding value from the parameter.
  1106. //
  1107. ui8ChannelNum = ui32Mapping & 0xff;
  1108. ui32Mapping = ui32Mapping >> 16;
  1109. //
  1110. // Find the uDMA channel mapping register and shift value to use for this
  1111. // channel
  1112. //
  1113. ui32MapReg = UDMA_CHMAP0 + (uint32_t)((ui8ChannelNum / 8) * 4);
  1114. ui8MapShift = (ui8ChannelNum % 8) * 4;
  1115. //
  1116. // Set the channel map encoding for this channel
  1117. //
  1118. HWREG(ui32MapReg) = (HWREG(ui32MapReg) & ~(0xf << ui8MapShift)) |
  1119. ui32Mapping << ui8MapShift;
  1120. }
  1121. //*****************************************************************************
  1122. //
  1123. // Close the Doxygen group.
  1124. //! @}
  1125. //
  1126. //*****************************************************************************