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