i2s.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. //*****************************************************************************
  2. //
  3. // i2s.c
  4. //
  5. // Driver for the I2S interface.
  6. //
  7. // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
  8. //
  9. //
  10. // Redistribution and use in source and binary forms, with or without
  11. // modification, are permitted provided that the following conditions
  12. // are met:
  13. //
  14. // Redistributions of source code must retain the above copyright
  15. // notice, this list of conditions and the following disclaimer.
  16. //
  17. // Redistributions in binary form must reproduce the above copyright
  18. // notice, this list of conditions and the following disclaimer in the
  19. // documentation and/or other materials provided with the
  20. // distribution.
  21. //
  22. // Neither the name of Texas Instruments Incorporated nor the names of
  23. // its contributors may be used to endorse or promote products derived
  24. // from this software without specific prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  29. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  30. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  31. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  32. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  33. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  34. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  36. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. //
  38. //*****************************************************************************
  39. //*****************************************************************************
  40. //
  41. //! \addtogroup I2S_api
  42. //! @{
  43. //
  44. //*****************************************************************************
  45. #include "inc/hw_types.h"
  46. #include "inc/hw_ints.h"
  47. #include "inc/hw_memmap.h"
  48. #include "inc/hw_mcasp.h"
  49. #include "inc/hw_apps_config.h"
  50. #include "interrupt.h"
  51. #include "i2s.h"
  52. //*****************************************************************************
  53. // Macros
  54. //*****************************************************************************
  55. #define MCASP_GBL_RCLK 0x00000001
  56. #define MCASP_GBL_RHCLK 0x00000002
  57. #define MCASP_GBL_RSER 0x00000004
  58. #define MCASP_GBL_RSM 0x00000008
  59. #define MCASP_GBL_RFSYNC 0x00000010
  60. #define MCASP_GBL_XCLK 0x00000100
  61. #define MCASP_GBL_XHCLK 0x00000200
  62. #define MCASP_GBL_XSER 0x00000400
  63. #define MCASP_GBL_XSM 0x00000800
  64. #define MCASP_GBL_XFSYNC 0x00001000
  65. //*****************************************************************************
  66. //
  67. //! \internal
  68. //! Releases the specifed submodule out of reset.
  69. //!
  70. //! \param ulBase is the base address of the I2S module.
  71. //! \param ulFlag is one of the valid sub module.
  72. //!
  73. //! This function Releases the specifed submodule out of reset.
  74. //!
  75. //! \return None.
  76. //
  77. //*****************************************************************************
  78. static void I2SGBLEnable(unsigned long ulBase, unsigned long ulFlag)
  79. {
  80. unsigned long ulReg;
  81. //
  82. // Read global control register
  83. //
  84. ulReg = HWREG(ulBase + MCASP_O_GBLCTL);
  85. //
  86. // Remove the sub modules reset as specified by ulFlag parameter
  87. //
  88. ulReg |= ulFlag;
  89. //
  90. // Write the configuration
  91. //
  92. HWREG(ulBase + MCASP_O_GBLCTL) = ulReg;
  93. //
  94. // Wait for write completeion
  95. //
  96. while(HWREG(ulBase + MCASP_O_GBLCTL) != ulReg)
  97. {
  98. }
  99. }
  100. //*****************************************************************************
  101. //
  102. //! Enables transmit and/or receive.
  103. //!
  104. //! \param ulBase is the base address of the I2S module.
  105. //! \param ulMode is one of the valid modes.
  106. //!
  107. //! This function enables the I2S module in specified mode. The parameter
  108. //! \e ulMode should be one of the following
  109. //!
  110. //! -\b I2S_MODE_TX_ONLY
  111. //! -\b I2S_MODE_TX_RX_SYNC
  112. //!
  113. //! \return None.
  114. //
  115. //*****************************************************************************
  116. void I2SEnable(unsigned long ulBase, unsigned long ulMode)
  117. {
  118. //
  119. // FSYNC and Bit clock are output only in master mode
  120. //
  121. if( HWREG(ulBase + MCASP_O_ACLKXCTL) & 0x20)
  122. {
  123. //
  124. // Set FSYNC anc BitClk as output
  125. //
  126. HWREG(ulBase + MCASP_O_PDIR) |= 0x14000000;
  127. }
  128. if(ulMode & 0x2)
  129. {
  130. //
  131. // Remove Rx HCLK reset
  132. //
  133. I2SGBLEnable(ulBase, MCASP_GBL_RHCLK);
  134. //
  135. // Remove Rx XCLK reset
  136. //
  137. I2SGBLEnable(ulBase, MCASP_GBL_RCLK);
  138. //
  139. // Enable Rx SERDES(s)
  140. //
  141. I2SGBLEnable(ulBase, MCASP_GBL_RSER);
  142. //
  143. // Enable Rx state machine
  144. //
  145. I2SGBLEnable(ulBase, MCASP_GBL_RSM);
  146. //
  147. // Enable FSync generator
  148. //
  149. I2SGBLEnable(ulBase, MCASP_GBL_RFSYNC);
  150. }
  151. //
  152. // Remove Tx HCLK reset
  153. //
  154. I2SGBLEnable(ulBase, MCASP_GBL_XHCLK);
  155. //
  156. // Remove Tx XCLK reset
  157. //
  158. I2SGBLEnable(ulBase, MCASP_GBL_XCLK);
  159. if(ulMode & 0x1)
  160. {
  161. //
  162. // Enable Tx SERDES(s)
  163. //
  164. I2SGBLEnable(ulBase, MCASP_GBL_XSER);
  165. //
  166. // Enable Tx state machine
  167. //
  168. I2SGBLEnable(ulBase, MCASP_GBL_XSM);
  169. }
  170. //
  171. // Enable FSync generator
  172. //
  173. I2SGBLEnable(ulBase, MCASP_GBL_XFSYNC);
  174. }
  175. //*****************************************************************************
  176. //
  177. //! Disables transmit and/or receive.
  178. //!
  179. //! \param ulBase is the base address of the I2S module.
  180. //!
  181. //! This function disables transmit and/or receive from I2S module.
  182. //!
  183. //! \return None.
  184. //
  185. //*****************************************************************************
  186. void I2SDisable(unsigned long ulBase)
  187. {
  188. //
  189. // Reset all sub modules
  190. //
  191. HWREG(ulBase + MCASP_O_GBLCTL) = 0;
  192. //
  193. // Wait for write to complete
  194. //
  195. while( HWREG(ulBase + MCASP_O_GBLCTL) != 0)
  196. {
  197. }
  198. }
  199. //*****************************************************************************
  200. //
  201. //! Waits to send data over the specified data line
  202. //!
  203. //! \param ulBase is the base address of the I2S module.
  204. //! \param ulDataLine is one of the valid data lines.
  205. //! \param ulData is the data to be transmitted.
  206. //!
  207. //! This function sends the \e ucData to the transmit register for the
  208. //! specified data line. If there is no space available, this
  209. //! function waits until there is space available before returning.
  210. //!
  211. //! \return None.
  212. //
  213. //*****************************************************************************
  214. void I2SDataPut(unsigned long ulBase, unsigned long ulDataLine,
  215. unsigned long ulData)
  216. {
  217. //
  218. // Compute register the offeset
  219. //
  220. ulDataLine = (ulDataLine-1) << 2;
  221. //
  222. // Wait for free space in fifo
  223. //
  224. while(!( HWREG(ulBase + MCASP_O_TXSTAT) & MCASP_TXSTAT_XDATA))
  225. {
  226. }
  227. //
  228. // Write Data into the FIFO
  229. //
  230. HWREG(ulBase + MCASP_O_TXBUF0 + ulDataLine) = ulData;
  231. }
  232. //*****************************************************************************
  233. //
  234. //! Sends data over the specified data line
  235. //!
  236. //! \param ulBase is the base address of the I2S module.
  237. //! \param ulDataLine is one of the valid data lines.
  238. //! \param ulData is the data to be transmitted.
  239. //!
  240. //! This function writes the \e ucData to the transmit register for
  241. //! the specified data line. This function does not block, so if there is no
  242. //! space available, then \b -1 is returned, and the application must retry the
  243. //! function later.
  244. //!
  245. //! \return Returns 0 on success, -1 otherwise.
  246. //
  247. //*****************************************************************************
  248. long I2SDataPutNonBlocking(unsigned long ulBase, unsigned long ulDataLine,
  249. unsigned long ulData)
  250. {
  251. //
  252. // Compute register the offeset
  253. //
  254. ulDataLine = (ulDataLine-1) << 2;
  255. //
  256. // Send Data if fifo has free space
  257. //
  258. if( HWREG(ulBase + MCASP_O_TXSTAT) & MCASP_TXSTAT_XDATA)
  259. {
  260. //
  261. // Write data into the FIFO
  262. //
  263. HWREG(ulBase + MCASP_O_TXBUF0 + ulDataLine) = ulData;
  264. return 0;
  265. }
  266. //
  267. // FIFO is full
  268. //
  269. return(-1);
  270. }
  271. //*****************************************************************************
  272. //
  273. //! Waits for data from the specified data line.
  274. //!
  275. //! \param ulBase is the base address of the I2S module.
  276. //! \param ulDataLine is one of the valid data lines.
  277. //! \param pulData is pointer to receive data variable.
  278. //!
  279. //! This function gets data from the receive register for the specified
  280. //! data line. If there are no data available, this function waits until a
  281. //! receive before returning.
  282. //!
  283. //! \return None.
  284. //
  285. //*****************************************************************************
  286. void I2SDataGet(unsigned long ulBase, unsigned long ulDataLine,
  287. unsigned long *pulData)
  288. {
  289. //
  290. // Compute register the offeset
  291. //
  292. ulDataLine = (ulDataLine-1) << 2;
  293. //
  294. // Wait for atleat on word in FIFO
  295. //
  296. while(!(HWREG(ulBase + MCASP_O_RXSTAT) & MCASP_RXSTAT_RDATA))
  297. {
  298. }
  299. //
  300. // Read the Data
  301. //
  302. *pulData = HWREG(ulBase + MCASP_O_RXBUF0 + ulDataLine);
  303. }
  304. //*****************************************************************************
  305. //
  306. //! Receives data from the specified data line.
  307. //!
  308. //! \param ulBase is the base address of the I2S module.
  309. //! \param ulDataLine is one of the valid data lines.
  310. //! \param pulData is pointer to receive data variable.
  311. //!
  312. //! This function gets data from the receive register for the specified
  313. //! data line.
  314. //!
  315. //!
  316. //! \return Returns 0 on success, -1 otherwise.
  317. //
  318. //*****************************************************************************
  319. long I2SDataGetNonBlocking(unsigned long ulBase, unsigned long ulDataLine,
  320. unsigned long *pulData)
  321. {
  322. //
  323. // Compute register the offeset
  324. //
  325. ulDataLine = (ulDataLine-1) << 2;
  326. //
  327. // Check if data is available in FIFO
  328. //
  329. if(HWREG(ulBase + MCASP_O_RXSTAT) & MCASP_RXSTAT_RDATA)
  330. {
  331. //
  332. // Read the Data
  333. //
  334. *pulData = HWREG(ulBase + MCASP_O_RXBUF0 + ulDataLine);
  335. return 0;
  336. }
  337. //
  338. // FIFO is empty
  339. //
  340. return -1;
  341. }
  342. //*****************************************************************************
  343. //
  344. //! Sets the configuration of the I2S module.
  345. //!
  346. //! \param ulBase is the base address of the I2S module.
  347. //! \param ulI2SClk is the rate of the clock supplied to the I2S module.
  348. //! \param ulBitClk is the desired bit rate.
  349. //! \param ulConfig is the data format.
  350. //!
  351. //! This function configures the I2S for operation in the specified data
  352. //! format. The bit rate is provided in the \e ulBitClk parameter and the data
  353. //! format in the \e ulConfig parameter.
  354. //!
  355. //! The \e ulConfig parameter is the logical OR of three values: the slot size
  356. //! the data read/write port select, Master or Slave mode
  357. //!
  358. //! Follwoing selects the Master-Slave mode
  359. //! -\b I2S_MODE_MASTER
  360. //! -\b I2S_MODE_SLAVE
  361. //!
  362. //! Following selects the slot size:
  363. //! -\b I2S_SLOT_SIZE_24
  364. //! -\b I2S_SLOT_SIZE_16
  365. //!
  366. //! Following selects the data read/write port:
  367. //! -\b I2S_PORT_DMA
  368. //! -\b I2S_PORT_CPU
  369. //!
  370. //! \return None.
  371. //
  372. //*****************************************************************************
  373. void I2SConfigSetExpClk(unsigned long ulBase, unsigned long ulI2SClk,
  374. unsigned long ulBitClk, unsigned long ulConfig)
  375. {
  376. unsigned long ulHClkDiv;
  377. unsigned long ulClkDiv;
  378. unsigned long ulSlotSize;
  379. unsigned long ulBitMask;
  380. //
  381. // Calculate clock dividers
  382. //
  383. ulHClkDiv = ((ulI2SClk/ulBitClk)-1);
  384. ulClkDiv = 0;
  385. //
  386. // Check if HCLK divider is overflowing
  387. //
  388. if(ulHClkDiv > 0xFFF)
  389. {
  390. ulHClkDiv = 0xFFF;
  391. //
  392. // Calculate clock divider
  393. //
  394. ulClkDiv = ((ulI2SClk/(ulBitClk * (ulHClkDiv + 1))) & 0x1F);
  395. }
  396. //
  397. //
  398. //
  399. ulClkDiv = ((ulConfig & I2S_MODE_SLAVE )?0x80:0xA0|ulClkDiv);
  400. HWREG(ulBase + MCASP_O_ACLKXCTL) = ulClkDiv;
  401. HWREG(ulBase + MCASP_O_AHCLKXCTL) = (0x8000|ulHClkDiv);
  402. //
  403. // Write the Tx format register
  404. //
  405. HWREG(ulBase + MCASP_O_TXFMT) = (0x18000 | (ulConfig & 0x7FFF));
  406. //
  407. // Write the Rx format register
  408. //
  409. HWREG(ulBase + MCASP_O_RXFMT) = (0x18000 | ((ulConfig >> 16) &0x7FFF));
  410. //
  411. // Check if in master mode
  412. //
  413. if( ulConfig & I2S_MODE_SLAVE)
  414. {
  415. //
  416. // Configure Tx FSync generator in I2S mode
  417. //
  418. HWREG(ulBase + MCASP_O_TXFMCTL) = 0x111;
  419. //
  420. // Configure Rx FSync generator in I2S mode
  421. //
  422. HWREG(ulBase + MCASP_O_RXFMCTL) = 0x111;
  423. }
  424. else
  425. {
  426. //
  427. // Configure Tx FSync generator in I2S mode
  428. //
  429. HWREG(ulBase + MCASP_O_TXFMCTL) = 0x113;
  430. //
  431. // Configure Rx FSync generator in I2S mode
  432. //
  433. HWREG(ulBase + MCASP_O_RXFMCTL) = 0x113;
  434. }
  435. //
  436. // Compute Slot Size
  437. //
  438. ulSlotSize = ((((ulConfig & 0xFF) >> 4) + 1) * 2);
  439. //
  440. // Creat the bit mask
  441. //
  442. ulBitMask = (0xFFFFFFFF >> (32 - ulSlotSize));
  443. //
  444. // Set Tx bit valid mask
  445. //
  446. HWREG(ulBase + MCASP_O_TXMASK) = ulBitMask;
  447. //
  448. // Set Rx bit valid mask
  449. //
  450. HWREG(ulBase + MCASP_O_RXMASK) = ulBitMask;
  451. //
  452. // Set Tx slot valid mask
  453. //
  454. HWREG(ulBase + MCASP_O_TXTDM) = 0x3;
  455. //
  456. // Set Rx slot valid mask
  457. //
  458. HWREG(ulBase + MCASP_O_RXTDM) = 0x3;
  459. }
  460. //*****************************************************************************
  461. //
  462. //! Configure and enable transmit FIFO.
  463. //!
  464. //! \param ulBase is the base address of the I2S module.
  465. //! \param ulTxLevel is the transmit FIFO DMA request level.
  466. //! \param ulWordsPerTransfer is the nuber of words transferred from the FIFO.
  467. //!
  468. //! This function configures and enable I2S transmit FIFO.
  469. //!
  470. //! The parameter \e ulTxLevel sets the level at which transmit DMA requests
  471. //! are generated. This should be non-zero integer multiple of number of
  472. //! serializers enabled as transmitters
  473. //!
  474. //! The parameter \e ulWordsPerTransfer sets the number of words that are
  475. //! transferred from the transmit FIFO to the data line(s). This value must
  476. //! equal the number of serializers used as transmitters.
  477. //!
  478. //! \return None.
  479. //
  480. //*****************************************************************************
  481. void I2STxFIFOEnable(unsigned long ulBase, unsigned long ulTxLevel,
  482. unsigned long ulWordsPerTransfer)
  483. {
  484. //
  485. // Set transmit FIFO configuration and
  486. // enable it
  487. //
  488. HWREG(ulBase + MCASP_0_WFIFOCTL) = ((1 <<16) | ((ulTxLevel & 0xFF) << 8)
  489. | (ulWordsPerTransfer & 0x1F));
  490. }
  491. //*****************************************************************************
  492. //
  493. //! Disables transmit FIFO.
  494. //!
  495. //! \param ulBase is the base address of the I2S module.
  496. //!
  497. //! This function disables the I2S transmit FIFO.
  498. //!
  499. //! \return None.
  500. //
  501. //*****************************************************************************
  502. void I2STxFIFODisable(unsigned long ulBase)
  503. {
  504. //
  505. // Disable transmit FIFO.
  506. //
  507. HWREG(ulBase + MCASP_0_WFIFOCTL) = 0;
  508. }
  509. //*****************************************************************************
  510. //
  511. //! Configure and enable receive FIFO.
  512. //!
  513. //! \param ulBase is the base address of the I2S module.
  514. //! \param ulRxLevel is the receive FIFO DMA request level.
  515. //! \param ulWordsPerTransfer is the nuber of words transferred from the FIFO.
  516. //!
  517. //! This function configures and enable I2S receive FIFO.
  518. //!
  519. //! The parameter \e ulRxLevel sets the level at which receive DMA requests
  520. //! are generated. This should be non-zero integer multiple of number of
  521. //! serializers enabled as receivers.
  522. //!
  523. //! The parameter \e ulWordsPerTransfer sets the number of words that are
  524. //! transferred to the receive FIFO from the data line(s). This value must
  525. //! equal the number of serializers used as receivers.
  526. //!
  527. //! \return None.
  528. //
  529. //*****************************************************************************
  530. void I2SRxFIFOEnable(unsigned long ulBase, unsigned long ulRxLevel,
  531. unsigned long ulWordsPerTransfer)
  532. {
  533. //
  534. // Set FIFO configuration
  535. //
  536. HWREG(ulBase + MCASP_0_RFIFOCTL) = ( (1 <<16) | ((ulRxLevel & 0xFF) << 8)
  537. | (ulWordsPerTransfer & 0x1F));
  538. }
  539. //*****************************************************************************
  540. //
  541. //! Disables receive FIFO.
  542. //!
  543. //! \param ulBase is the base address of the I2S module.
  544. //!
  545. //! This function disables the I2S receive FIFO.
  546. //!
  547. //! \return None.
  548. //
  549. //*****************************************************************************
  550. void I2SRxFIFODisable(unsigned long ulBase)
  551. {
  552. //
  553. // Disable receive FIFO.
  554. //
  555. HWREG(ulBase + MCASP_0_RFIFOCTL) = 0;
  556. }
  557. //*****************************************************************************
  558. //
  559. //! Get the transmit FIFO status.
  560. //!
  561. //! \param ulBase is the base address of the I2S module.
  562. //!
  563. //! This function gets the number of 32-bit words currently in the transmit
  564. //! FIFO.
  565. //!
  566. //! \return Returns transmit FIFO status.
  567. //
  568. //*****************************************************************************
  569. unsigned long I2STxFIFOStatusGet(unsigned long ulBase)
  570. {
  571. //
  572. // Return transmit FIFO level
  573. //
  574. return HWREG(ulBase + MCASP_0_WFIFOSTS);
  575. }
  576. //*****************************************************************************
  577. //
  578. //! Get the receive FIFO status.
  579. //!
  580. //! \param ulBase is the base address of the I2S module.
  581. //!
  582. //! This function gets the number of 32-bit words currently in the receive
  583. //! FIFO.
  584. //!
  585. //! \return Returns receive FIFO status.
  586. //
  587. //*****************************************************************************
  588. unsigned long I2SRxFIFOStatusGet(unsigned long ulBase)
  589. {
  590. //
  591. // Return receive FIFO level
  592. //
  593. return HWREG(ulBase + MCASP_0_RFIFOSTS);
  594. }
  595. //*****************************************************************************
  596. //
  597. //! Configure the serializer in specified mode.
  598. //!
  599. //! \param ulBase is the base address of the I2S module.
  600. //! \param ulDataLine is the data line (serilizer) to be configured.
  601. //! \param ulSerMode is the required serializer mode.
  602. //! \param ulInActState sets the inactive state of the data line.
  603. //!
  604. //! This function configure and enable the serializer associated with the given
  605. //! data line in specified mode.
  606. //!
  607. //! The paramenter \e ulDataLine selects to data line to be configured and
  608. //! can be one of the following:
  609. //! -\b I2S_DATA_LINE_0
  610. //! -\b I2S_DATA_LINE_1
  611. //!
  612. //! The parameter \e ulSerMode can be one of the following:
  613. //! -\b I2S_SER_MODE_TX
  614. //! -\b I2S_SER_MODE_RX
  615. //! -\b I2S_SER_MODE_DISABLE
  616. //!
  617. //! The parameter \e ulInActState can be one of the following
  618. //! -\b I2S_INACT_TRI_STATE
  619. //! -\b I2S_INACT_LOW_LEVEL
  620. //! -\b I2S_INACT_LOW_HIGH
  621. //!
  622. //! \return Returns receive FIFO status.
  623. //
  624. //*****************************************************************************
  625. void I2SSerializerConfig(unsigned long ulBase, unsigned long ulDataLine,
  626. unsigned long ulSerMode, unsigned long ulInActState)
  627. {
  628. if( ulSerMode == I2S_SER_MODE_TX)
  629. {
  630. //
  631. // Set the data line in output mode
  632. //
  633. HWREG(ulBase + MCASP_O_PDIR) |= ulDataLine;
  634. }
  635. else
  636. {
  637. //
  638. // Set the data line in input mode
  639. //
  640. HWREG(ulBase + MCASP_O_PDIR) &= ~ulDataLine;
  641. }
  642. //
  643. // Set the serializer configuration.
  644. //
  645. HWREG(ulBase + MCASP_O_XRSRCTL0 + ((ulDataLine-1) << 2))
  646. = (ulSerMode | ulInActState);
  647. }
  648. //*****************************************************************************
  649. //
  650. //! Enables individual I2S interrupt sources.
  651. //!
  652. //! \param ulBase is the base address of the I2S module.
  653. //! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
  654. //!
  655. //! This function enables the indicated I2S interrupt sources. Only the
  656. //! sources that are enabled can be reflected to the processor interrupt;
  657. //! disabled sources have no effect on the processor.
  658. //!
  659. //! The \e ulIntFlags parameter is the logical OR of any of the following:
  660. //!
  661. //! -\b I2S_INT_XUNDRN
  662. //! -\b I2S_INT_XSYNCERR
  663. //! -\b I2S_INT_XLAST
  664. //! -\b I2S_INT_XDATA
  665. //! -\b I2S_INT_XSTAFRM
  666. //! -\b I2S_INT_XDMA
  667. //! -\b I2S_INT_ROVRN
  668. //! -\b I2S_INT_RSYNCERR
  669. //! -\b I2S_INT_RLAST
  670. //! -\b I2S_INT_RDATA
  671. //! -\b I2S_INT_RSTAFRM
  672. //! -\b I2S_INT_RDMA
  673. //!
  674. //! \return None.
  675. //
  676. //*****************************************************************************
  677. void I2SIntEnable(unsigned long ulBase, unsigned long ulIntFlags)
  678. {
  679. //
  680. // Enable DMA done interrupts
  681. //
  682. HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_CLR )
  683. |= ((ulIntFlags &0xC0000000) >> 20);
  684. //
  685. // Enable specific Tx Interrupts
  686. //
  687. HWREG(ulBase + MCASP_O_EVTCTLX) |= (ulIntFlags & 0xFF);
  688. //
  689. // Enable specific Rx Interrupts
  690. //
  691. HWREG(ulBase + MCASP_O_EVTCTLR) |= ((ulIntFlags >> 16) & 0xFF);
  692. }
  693. //*****************************************************************************
  694. //
  695. //! Disables individual I2S interrupt sources.
  696. //!
  697. //! \param ulBase is the base address of the I2S module.
  698. //! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
  699. //!
  700. //! This function disables the indicated I2S interrupt sources. Only the
  701. //! sources that are enabled can be reflected to the processor interrupt;
  702. //! disabled sources have no effect on the processor.
  703. //!
  704. //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
  705. //! parameter to I2SIntEnable().
  706. //!
  707. //! \return None.
  708. //
  709. //*****************************************************************************
  710. void I2SIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
  711. {
  712. //
  713. // Disable DMA done interrupts
  714. //
  715. HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_SET)
  716. |= ((ulIntFlags &0xC0000000) >> 20);
  717. //
  718. // Disable specific Tx Interrupts
  719. //
  720. HWREG(ulBase + MCASP_O_EVTCTLX) &= ~(ulIntFlags & 0xFF);
  721. //
  722. // Disable specific Rx Interrupts
  723. //
  724. HWREG(ulBase + MCASP_O_EVTCTLR) &= ~((ulIntFlags >> 16) & 0xFF);
  725. }
  726. //*****************************************************************************
  727. //
  728. //! Gets the current interrupt status.
  729. //!
  730. //! \param ulBase is the base address of the I2S module.
  731. //!
  732. //! This function returns the raw interrupt status for I2S enumerated
  733. //! as a bit field of values:
  734. //! -\b I2S_STS_XERR
  735. //! -\b I2S_STS_XDMAERR
  736. //! -\b I2S_STS_XSTAFRM
  737. //! -\b I2S_STS_XDATA
  738. //! -\b I2S_STS_XLAST
  739. //! -\b I2S_STS_XSYNCERR
  740. //! -\b I2S_STS_XUNDRN
  741. //! -\b I2S_STS_XDMA
  742. //! -\b I2S_STS_RERR
  743. //! -\b I2S_STS_RDMAERR
  744. //! -\b I2S_STS_RSTAFRM
  745. //! -\b I2S_STS_RDATA
  746. //! -\b I2S_STS_RLAST
  747. //! -\b I2S_STS_RSYNCERR
  748. //! -\b I2S_STS_ROVERN
  749. //! -\b I2S_STS_RDMA
  750. //!
  751. //! \return Returns the current interrupt status, enumerated as a bit field of
  752. //! values described above.
  753. //
  754. //*****************************************************************************
  755. unsigned long I2SIntStatus(unsigned long ulBase)
  756. {
  757. unsigned long ulStatus;
  758. //
  759. // Get DMA interrupt status
  760. //
  761. ulStatus =
  762. HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_STS_RAW) << 20;
  763. ulStatus &= 0xC0000000;
  764. //
  765. // Read Tx Interrupt status
  766. //
  767. ulStatus |= HWREG(ulBase + MCASP_O_TXSTAT);
  768. //
  769. // Read Rx Interrupt status
  770. //
  771. ulStatus |= HWREG(ulBase + MCASP_O_RXSTAT) << 16;
  772. //
  773. // Return the status
  774. //
  775. return ulStatus;
  776. }
  777. //*****************************************************************************
  778. //
  779. //! Clears I2S interrupt sources.
  780. //!
  781. //! \param ulBase is the base address of the I2S module.
  782. //! \param ulStatFlags is a bit mask of the interrupt sources to be cleared.
  783. //!
  784. //! The specified I2S interrupt sources are cleared, so that they no longer
  785. //! assert. This function must be called in the interrupt handler to keep the
  786. //! interrupt from being recognized again immediately upon exit.
  787. //!
  788. //! The \e ulIntFlags parameter is the logical OR of any of the value
  789. //! describe in I2SIntStatus().
  790. //!
  791. //! \return None.
  792. //
  793. //*****************************************************************************
  794. void I2SIntClear(unsigned long ulBase, unsigned long ulStatFlags)
  795. {
  796. //
  797. // Clear DMA done interrupts
  798. //
  799. HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_ACK)
  800. |= ((ulStatFlags &0xC0000000) >> 20);
  801. //
  802. // Clear Tx Interrupt
  803. //
  804. HWREG(ulBase + MCASP_O_TXSTAT) = ulStatFlags & 0x1FF ;
  805. //
  806. // Clear Rx Interrupt
  807. //
  808. HWREG(ulBase + MCASP_O_RXSTAT) = (ulStatFlags >> 16) & 0x1FF;
  809. }
  810. //*****************************************************************************
  811. //
  812. //! Registers an interrupt handler for a I2S interrupt.
  813. //!
  814. //! \param ulBase is the base address of the I2S module.
  815. //! \param pfnHandler is a pointer to the function to be called when the
  816. //! I2S interrupt occurs.
  817. //!
  818. //! This function does the actual registering of the interrupt handler. This
  819. //! function enables the global interrupt in the interrupt controller; specific
  820. //! I2S interrupts must be enabled via I2SIntEnable(). It is the interrupt
  821. //! handler's responsibility to clear the interrupt source.
  822. //!
  823. //! \sa IntRegister() for important information about registering interrupt
  824. //! handlers.
  825. //!
  826. //! \return None.
  827. //
  828. //*****************************************************************************
  829. void I2SIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
  830. {
  831. //
  832. // Register the interrupt handler
  833. //
  834. IntRegister(INT_I2S,pfnHandler);
  835. //
  836. // Enable the interrupt
  837. //
  838. IntEnable(INT_I2S);
  839. }
  840. //*****************************************************************************
  841. //
  842. //! Unregisters an interrupt handler for a I2S interrupt.
  843. //!
  844. //! \param ulBase is the base address of the I2S module.
  845. //!
  846. //! This function does the actual unregistering of the interrupt handler. It
  847. //! clears the handler to be called when a I2S interrupt occurs. This
  848. //! function also masks off the interrupt in the interrupt controller so that
  849. //! the interrupt handler no longer is called.
  850. //!
  851. //! \sa IntRegister() for important information about registering interrupt
  852. //! handlers.
  853. //!
  854. //! \return None.
  855. //
  856. //*****************************************************************************
  857. void I2SIntUnregister(unsigned long ulBase)
  858. {
  859. //
  860. // Disable interrupt
  861. //
  862. IntDisable(INT_I2S);
  863. //
  864. // Unregister the handler
  865. //
  866. IntUnregister(INT_I2S);
  867. }
  868. //*****************************************************************************
  869. //
  870. //! Set the active slots for Trasmitter
  871. //!
  872. //! \param ulBase is the base address of the I2S module.
  873. //! \param ulActSlot is the bit-mask of activ slots
  874. //!
  875. //! This function sets the active slots for the transmitter. By default both
  876. //! the slots are active. The parameter \e ulActSlot is logical OR follwoing
  877. //! values:
  878. //! -\b I2S_ACT_SLOT_EVEN
  879. //! -\b I2S_ACT_SLOT_ODD
  880. //!
  881. //! \return None.
  882. //
  883. //*****************************************************************************
  884. void I2STxActiveSlotSet(unsigned long ulBase, unsigned long ulActSlot)
  885. {
  886. HWREG(ulBase + MCASP_O_TXTDM) = ulActSlot;
  887. }
  888. //*****************************************************************************
  889. //
  890. //! Set the active slots for Receiver
  891. //!
  892. //! \param ulBase is the base address of the I2S module.
  893. //! \param ulActSlot is the bit-mask of activ slots
  894. //!
  895. //! This function sets the active slots for the receiver. By default both
  896. //! the slots are active. The parameter \e ulActSlot is logical OR follwoing
  897. //! values:
  898. //! -\b I2S_ACT_SLOT_EVEN
  899. //! -\b I2S_ACT_SLOT_ODD
  900. //!
  901. //! \return None.
  902. //
  903. //*****************************************************************************
  904. void I2SRxActiveSlotSet(unsigned long ulBase, unsigned long ulActSlot)
  905. {
  906. HWREG(ulBase + MCASP_O_RXTDM) = ulActSlot;
  907. }
  908. //*****************************************************************************
  909. //
  910. // Close the Doxygen group.
  911. //! @}
  912. //
  913. //*****************************************************************************