This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320C5535: MMCSD Wav file integrated with I2S_AudioCodec_DMA

Part Number: TMS320C5535

Tool/software:

Hi 

I have an example program located at C:\ti\c55_lp\c55_csl_3.08.01\ccs_v6.x_examples\mmc_sd\CSL_MMCSD_SdCardFSExtExample

void mmcFileTest(void)
{
    CSL_Status    status;
    AtaError      ataStatus;
    Bool          testFailed;

    testFailed = FALSE;

    printf("MMCSD-ATAFS TESTS!\n\n");

//  printf("MMCSD-ATAFS POLL MODE TEST!\n\n");
//
//  status = configSdCard(CSL_MMCSD_OPMODE_POLLED);
//  if(status != CSL_SOK)
//  {
//      testFailed = TRUE;
//   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --
//   /////  Reseting PaSs_StAtE to 0 if error detected here.
//        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
//   /////
//      printf("SD card initialization Failed\n");
//      printf("\nMMCSD-ATAFS POLL MODE TEST FAILED!!\n");
//  }
//  else
//  {
//      printf("SD card initialization Successful\n");
//      ataStatus = mmcConfigFs("polled");
//      if(ataStatus != ATA_ERROR_NONE)
//      {
//          testFailed = TRUE;
//   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --
//   /////  Reseting PaSs_StAtE to 0 if error detected here.
//        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
//   /////
//          printf("\nMMCSD-ATAFS POLL MODE TEST FAILED!!\n");
//      }
//      else
//      {
//          printf("\nMMCSD-ATAFS POLL MODE TEST PASSED!!\n");
//      }
//  }

    printf("\n\n\nMMCSD-ATAFS DMA MODE TEST!\n\n");

    status = configSdCard(CSL_MMCSD_OPMODE_DMA);
    if(status != CSL_SOK)
    {
        testFailed = TRUE;
   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --
   /////  Reseting PaSs_StAtE to 0 if error detected here.
        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
   /////
        printf("SD card initialization Failed\n");
        printf("\nMMCSD-ATAFS DMA MODE TEST FAILED!!\n");
    }
    else
    {
        printf("SD card initialization Successful\n");
        ataStatus = mmcConfigFs("sample");
        if(ataStatus != ATA_ERROR_NONE)
        {
            testFailed = TRUE;
   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --
   /////  Reseting PaSs_StAtE to 0 if error detected here.
        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
   /////
            printf("\nMMCSD-ATAFS DMA MODE TEST FAILED!!\n");
        }
        else
        {
            printf("\nMMCSD-ATAFS DMA MODE TEST PASSED!!\n");
        }
    }

   /////INSTRUMENTATION FOR BATCH TESTING -- Part 3 --
   /////  At program exit, copy "PaSs_StAtE" into "PaSs".
        PaSs = PaSs_StAtE; //If flow gets here, override PaSs' initial 0 with
   /////                   // pass/fail value determined during program execution.
   /////  Note:  Program should next exit to C$$EXIT and halt, where DSS, under
   /////   control of a host PC script, will read and record the PaSs' value.
   /////

    if (testFailed == TRUE)
    {
        printf("\n\nMMCSD-ATAFS TESTS FAILED!!\n\n");
        //exit(EXIT_FAILURE);
    }
    else
    {
        printf("\n\nMMCSD-ATAFS TESTS PASSED!!\n\n");
        //exit(EXIT_SUCCESS);
    }
}

/**
 *  \brief  Function to configure file system and perform
 *          read/write operations
 *
 *  \param  fileName - Name of the file to be created
 *
 *  \return Test result
 */
AtaError mmcConfigFs(char    *fileName)
{
//    Uint16        index;
    AtaError      ata_error;
    waveHeader    header;
    unsigned int diskType;

    ata_error = ATA_ERROR_NONE;

//    for(index = 0; index < CSL_MMCSD_ATA_BUF_SIZE; index++)
//    {
//        gMmcWriteBuf[index] = 0x4142;
//      AtaWrBuf[index] = 0x4344;
//        gMmcReadBuf[index]  = 0x0;
//    }

    /* Call init function initialize ATA state structure */
    gpstrAtaDrive->AtaInitAtaMediaState = (AtaError (*)(void *))MMC_initState;
    gpstrAtaMMCState->hMmcSd = mmcsdHandle;
    gpstrAtaDrive->pAtaMediaState = gpstrAtaMMCState;
    gpstrAtaDrive->AtaInitAtaMediaState(gpstrAtaDrive);

    /* Set the temp write buffer */
    gpstrAtaDrive->_AtaWriteBuffer = AtaWrBuf;


    /* For partitioned disk, 'diskType' should be 0
       and for unpartiotioned disk, it should be 1
     */
     /* chk_mmc() function is used to check the partition type of
        SD card.
        ATA_systemInit() function needs to be called
        with 'diskType' set to 0 before calling chk_mmc().
        chk_mmc() function will check whether the disk is partitioned
        or unpartitioned. If disk is not partitioned it will change the
        'diskType' value to 1 otherwise it will not change the diskType value.
        After calling chk_mmc() if 'diskType' is not '0' , It means that
        the SD card is not partitioned and ATA_systemInit() needs to be
        called with 'diskType' value modified by chk_mmc() function */

    diskType = CSL_MMCSD_ATAFS_DISKTYPE;
    /* Call ATA_systemInit() to intialize some values whcih are
      used by chk_mmc() function */
    ata_error = ATA_systemInit(gpstrAtaDrive, diskType);

    chk_mmc(gpstrAtaDrive, &diskType);
    if(diskType != CSL_MMCSD_ATAFS_DISKTYPE)
    {
        ata_error = ATA_systemInit(gpstrAtaDrive, diskType);
        if(ata_error != ATA_ERROR_NONE)
        {
            printf("ATA_systemInit Failed\n");
            printf("Format the SD card\n");
            return(ata_error);
        }
    }

    printf("\nATA File System Initialization successful\n");

    /* Find the first file available */
    ata_error =  ATA_fileInit(gpstrAtaDrive, pAtaFile);
    if(ata_error) {
        printf("ATA_fileInit error (0x%x)\n", ata_error);
        return(ata_error);
    }

#if 0
    /* Set the file name */
    ATA_setFileName(pAtaFile, fileName, "wav");

    ata_error = ATA_create(pAtaFile);
#else
    ata_error = ATA_fopen(pAtaFile, fileName, "wav");
#endif
    if(ata_error != ATA_ERROR_NONE)
    {
        printf("ATA_fopen Failed\n");
        return(ata_error);
    }
    else
    {
        printf("\nFile Creation/Open on SD card is Successful\n");
    }

    /* Write data to the file */
//    ata_error = ATA_write(pAtaFile, gMmcWriteBuf, CSL_MMCSD_ATA_BUF_SIZE);
//    if(ata_error != ATA_ERROR_NONE)
//    {
//      printf("ATA_write Failed\n");
//        return(ata_error);
//    }
//    else
//    {
//      printf("\nWriting Data to the file on SD card successful\n");
//  }

    /* Reset the file pointer to the beginning */
    ATA_seek (pAtaFile, 0);

    /* Read the data from the file in little endian mode */
    ata_error = ATA_read(pAtaFile,gMmcReadBuf, sizeof(header));
    if(ata_error != ATA_ERROR_NONE)
    {
        printf("ATA_read Failed\n");
        return(ata_error);
    }
    else
    {
        printf("\nReading Data from the file on SD card successful\n");
    }

    extractWaveInfo(&header, gMmcReadBuf);


//    if(checkWaveHeader(&header))
//        {
//            printf("Invalid WAV file\n");
//           // return (ata_error);
//        }

        printf("WAV file details:\n");
        printf("Chunk ID: %08X\n", header.chunkID);
        printf("Chunk Size: %u\n", header.chunkSize);
        printf("Format: %08X\n", header.format);
        printf("Audio Format: %u\n", header.audioFormat);
        printf("Number of Channels: %u\n", header.numChannels);
        printf("Sample Rate: %u\n", header.sampleRate);
        printf("Byte Rate: %u\n", header.byteRate);
        printf("Block Align: %u\n", header.blockAlign);
        printf("Bits Per Sample: %u\n", header.bitsPerSample);
        printf("Subchunk2 Size: %u\n", header.subchunk2Size);


        size_t totalBytesRead = 0;
           size_t fileSize = header.subchunk2Size; // Size of audio data
           while (totalBytesRead < fileSize)
           {
               size_t bytesToRead = sizeof(gMmcReadBuf);
               if (fileSize - totalBytesRead < bytesToRead)
               {
                   bytesToRead = fileSize - totalBytesRead;
               }

               ata_error = ATA_read(pAtaFile, gMmcReadBuf, bytesToRead);
               if (ata_error != ATA_ERROR_NONE)
               {
                   printf("ATA_read Failed\n");
                   return(ata_error);
               }
               int i;
               for (i = 0; i < bytesToRead / 2; i++)  // Each Uint16 is 2 bytes
                     {
                         printf("%04X ", gMmcReadBuf[i]);
                         if ((i + 1) % 16 == 0) // Print a newline every 16 values
                         {
                             printf("\n");
                         }
                     }

               // Process the read data (e.g., store in a buffer, play audio, etc.)
               totalBytesRead += bytesToRead;

               if (totalBytesRead >= 256) // Print only the first 256 bytes
                       {
                           break;
                       }
           }



    /* Close the file */
    ata_error = ATA_close(pAtaFile);
    if(ata_error != ATA_ERROR_NONE)
    {
        printf("ATA_close Failed\n");
        return(ata_error);
    }

    /* Compare the data read and data written */
//    for(index = 0; index < CSL_MMCSD_ATA_BUF_SIZE; index++)
//    {
//        if(gMmcWriteBuf[index] != gMmcReadBuf[index])
//        {
//            ata_error = 1;
//            printf("\nMMCSD Read and Write Buffers do not Match\n");
//            break;
//        }
//    }
//
//    if(ata_error == 0)
//    {
//        printf("\nMMCSD Read and Write Buffers Match\n");
//    }

    return(ata_error);
}

/**
 *  \brief  Function to initialize and configure SD card
 *
 *  \param  opMode   - Operating Mode of MMCSD; POLL/DMA
 *
 *  \return Test result
 */
CSL_Status configSdCard (CSL_MMCSDOpMode    opMode)
{
    CSL_Status     status;
    Uint16         actCard;
    Uint16         clockDiv;
    Uint16         rca;
    CSL_CardType   cardType;

    cardType  = CSL_CARD_NONE;

    /* Get the clock divider value for the current CPU frequency */
    clockDiv = computeClkRate();

    /* Initialize MMCSD CSL module */
    status = MMC_init();

    status = SYS_setEBSR(CSL_EBSR_FIELD_SP0MODE,
                         CSL_EBSR_SP0MODE_0);
    status |= SYS_setEBSR(CSL_EBSR_FIELD_SP1MODE,
                         CSL_EBSR_SP1MODE_0);
    if(CSL_SOK != status)
    {
        printf("SYS_setEBSR failed\n");
        return (status);
    }

    /* Open MMCSD CSL module */
#ifdef C5515_EZDSP
    mmcsdHandle = MMC_open(&pMmcsdContObj, CSL_MMCSD1_INST,
                           opMode, &status);
#else
    mmcsdHandle = MMC_open(&pMmcsdContObj, CSL_MMCSD0_INST,
                           opMode, &status);
#endif
    if(mmcsdHandle == NULL)
    {
        printf("MMC_open Failed\n");
        return (status);
    }

    /* Configure the DMA in case of operating mode is set to DMA */
    if(opMode == CSL_MMCSD_OPMODE_DMA)
    {
        /* Initialize Dma */
        status = DMA_init();
        if (status != CSL_SOK)
        {
            printf("DMA_init Failed!\n");
            return(status);
        }

        /* Open Dma channel for MMCSD write */
        dmaWrHandle = DMA_open(CSL_DMA_CHAN0, &dmaWrChanObj, &status);
        if((dmaWrHandle == NULL) || (status != CSL_SOK))
        {
            printf("DMA_open for MMCSD Write Failed!\n");
            return(status);
        }

        /* Open Dma channel for MMCSD read */
        dmaRdHandle = DMA_open(CSL_DMA_CHAN1, &dmaRdChanObj, &status);
        if((dmaRdHandle == NULL) || (status != CSL_SOK))
        {
            printf("DMA_open for MMCSD Read Failed!\n");
            return(status);
        }

        /* Set the DMA handle for MMC read */
        status = MMC_setDmaHandle(mmcsdHandle, dmaWrHandle, dmaRdHandle);
        if(status != CSL_SOK)
        {
            printf("API: MMC_setDmaHandle for MMCSD Failed\n");
            return(status);
        }
    }

    /* Reset the SD card */
    status = MMC_sendGoIdle(mmcsdHandle);
    if(status != CSL_SOK)
    {
        printf("MMC_sendGoIdle Failed\n");
        return (status);
    }

    /* Check for the card */
    status = MMC_selectCard(mmcsdHandle, &mmcCardObj);
    if((status == CSL_ESYS_BADHANDLE) ||
       (status == CSL_ESYS_INVPARAMS))
    {
        printf("MMC_selectCard Failed\n");
        return (status);
    }

    /* Verify whether the SD card is detected or not */
    if(mmcCardObj.cardType == CSL_MMC_CARD)
    {
        printf("MMC Card Detected!\n\n");
        cardType = CSL_MMC_CARD;
#if 0
        cardAddr = (sectCount)*(CSL_MMCSD_BLOCK_LENGTH);
#endif
        /* Send the MMC card identification Data */
        status = MMC_sendAllCID(mmcsdHandle, &sdCardIdObj);
        if(status != CSL_SOK)
        {
            printf("API: MMC_sendAllCID Failed\n");
            return(status);
        }

        /* Set the MMC Relative Card Address */
        status = MMC_setRca(mmcsdHandle, &mmcCardObj, 0x0001);
        if(status != CSL_SOK)
        {
            printf("API: MMC_setRca Failed\n");
            return(status);
        }

        /* Read the MMC Card Specific Data */
        status = MMC_getCardCsd(mmcsdHandle, &sdCardCsdObj);
        if(status != CSL_SOK)
        {
            printf("API: MMC_getCardCsd Failed\n");
            return(status);
        }

        /* Get the clock divider value for the current CPU frequency */
        clockDiv = computeClkRate();
    }
    else if(mmcCardObj.cardType == CSL_SD_CARD)
    {
        printf("SD Card detected\n");
        cardType = CSL_SD_CARD;

        /* Check if the card is high capacity card */
        if(mmcsdHandle->cardObj->sdHcDetected == TRUE)
        {
            printf("SD card is High Capacity Card\n");
            printf("Memory Access will use Block Addressing\n");
        }
        else
        {
            printf("SD card is Standard Capacity Card\n");
            printf("Memory Access will use Byte Addressing\n");
        }

        /* Set the init clock */
        status = MMC_sendOpCond(mmcsdHandle, 70);
        if(status != CSL_SOK)
        {
            printf("MMC_sendOpCond Failed\n");
            return (status);
        }

        /* Send the card identification Data */
        status = SD_sendAllCID(mmcsdHandle, &sdCardIdObj);
        if(status != CSL_SOK)
        {
            printf("SD_sendAllCID Failed\n");
            return (status);
        }

        /* Set the Relative Card Address */
        status = SD_sendRca(mmcsdHandle, &mmcCardObj, &rca);
        if(status != CSL_SOK)
        {
            printf("SD_sendRca Failed\n");
            return (status);
        }

        /* Read the SD Card Specific Data */
        status = SD_getCardCsd(mmcsdHandle, &sdCardCsdObj);
        if(status != CSL_SOK)
        {
            printf("SD_getCardCsd Failed\n");
            return (status);
        }
    }
    else
    {
        if(mmcCardObj.cardType == CSL_CARD_NONE)
        {
            printf("No Card detected\n");
        }
        else
        {
            printf("SD Card not detected\n");
        }
        printf("Please Insert SD Card\n");
        return(CSL_ESYS_FAIL);
    }

    /* Set the card type in internal data structures */
    status = MMC_setCardType(&mmcCardObj, cardType);
    if(status != CSL_SOK)
    {
        printf("MMC_setCardType Failed\n");
        return (status);
    }

    /* Set the card pointer in internal data structures */
    status = MMC_setCardPtr(mmcsdHandle, &mmcCardObj);
    if(status != CSL_SOK)
    {
        printf("MMC_setCardPtr Failed\n");
        return (status);
    }

    /* Get the number of cards */
    status = MMC_getNumberOfCards(mmcsdHandle, &actCard);
    if(status != CSL_SOK)
    {
        printf("MMC_getNumberOfCards Failed\n");
        return (status);
    }

    /* Set clock for read-write access */
    status = MMC_sendOpCond(mmcsdHandle, clockDiv);
    if(status != CSL_SOK)
    {
        printf("MMC_sendOpCond Failed\n");
        return (status);
    }

    /* Set Endian mode for read and write operations */
    status = MMC_setEndianMode(mmcsdHandle, CSL_MMCSD_ENDIAN_LITTLE,
                               CSL_MMCSD_ENDIAN_LITTLE);
    if(status != CSL_SOK)
    {
        printf("MMC_setEndianMode Failed\n");
        return(status);
    }

    /* Set block length for the memory card
     * For high capacity cards setting the block length will have
     * no effect
     */
    status = MMC_setBlockLength(mmcsdHandle, CSL_MMCSD_BLOCK_LENGTH);
    if(status != CSL_SOK)
    {
        printf("MMC_setBlockLength Failed\n");
        return(status);
    }
#if 0
    for(looper = 0; looper < 256; looper++)
    {
        gMmcWriteBuf[looper] = 0xABCD;
    }

    /* Write data to the MMC card */
    status = MMC_write(mmcsdHandle, 0, 512,
                          gMmcWriteBuf);
    if(status != CSL_SOK)
    {
        printf("API: MMC_write Failed\n");
        return(status);
    }
    else
    {
        printf("API: MMC_write Successful\n");
    }

    /* Read data from the MMC card */
    status = MMC_read(mmcsdHandle, 0, 512,
                         gMmcReadBuf);
    if(status != CSL_SOK)
    {
        printf("API: MMC_read Failed\n");
        return(status);
    }
    else
    {
        printf("API: MMC_read Successful\n");
    }

//    /* Compare the MMC read and write buffers */
//    for(looper = 0; looper < 256; ++looper)
//    {
//        if(gMmcReadBuf[looper] != gMmcWriteBuf[looper])
//        {
//            printf("\nBuffer Miss Matched at Position %d\n",looper);
//            return(CSL_ESYS_FAIL);
//        }
//    }
#endif
    return (status);
}

which I have integrated with another example found at C:\ti\c55_lp\c55_csl_3.08.01\ccs_v6.x_examples\i2s\CSL_I2S_AudioCodec_DMA

/* ============================================================================
 * Copyright (c) 2008-2016 Texas Instruments Incorporated.
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/


/** @file csl_mmcsd_atafs_example.c
 *
 *  @brief MMCSD-ATAFS interface test code
 *
 *
 * \page    page12  MMCSD EXAMPLE DOCUMENTATION
 *
 * \section MMC10   MMCSD EXAMPLE10 - MMCSD-ATFS EXTENDED INTERFACE TEST
 *
 * \subsection MMC10x    TEST DESCRIPTION:
 *      This test code verifies the functionality of MMCSD-ATAFS interface.
 * ATA File System is used to create, write and read files on the SD card.
 * Files created by the ATFS can be read from windows PC using a card reader.
 *
 * During the test a file is created on the SD card, 512 bytes of data is
 * written to the file and the same data is read back. CSL MMCSD module
 * should be configured before initializing the file system. During the
 * card detection test code checks for the SD card.If no SD card is detected
 * test exits with error. After successful detection and configuration of the
 * SD card file system should be initialized using ATA_systemInit(). SD card
 * should be formatted to run this test. ATA_systemInit() function fails if
 * the card is not formatted. File with the given name is created using
 * ATA_create() API. 512 bytes of data is written to the file created using
 * ATA_write() API. After successful completion of write operation same data
 * is read from the card using ATA_readLittleEndian(). Write and read buffers
 * are compared for the data verification. The file created and data written
 * can be accessed using a SD card reader. This test is executed in both
 * polling and DMA modes.
 *
 * Maximum value of the clock at which memory data transaction takes place
 * can be controlled using the macro 'CSL_SD_CLOCK_MAX_KHZ'.
 * Depending on the clock at which CPU is running, SD clock will be configured
 * to the possible value that is nearest to the value defined by this macro.
 * SD clock will be configured to a value less than or equal to but not greater
 * than the value defined by this macro. Changing this macro value
 * will automatically change the memory clock divider value.
 * memory clock will be generated from the system clock based on equation
 *
 * @verbatim
   memory clock = (system clock) / (2 * (CLKRT + 1)
      - memory clock is clock for the memory card
      - system clock is clock at which CPU us running
      - CLKRT is value of clock rate configured in clock control register
   @endverbatim
 *
 * As per this equation memory clock that can be generated is always less than
 * or equal to half of the system clock value. Value of 'CLKRT' can range
 * from 0 to 255. Maximum and minimum memory clock values that can be generated
 * at a particular CPU frequency are limited by the minimum and maximum value
 * of the memory clock rate (CLKRT).
 *
 * NOTE: THIS TEST WORKS WITH ONLY SD CARD. SD CARD SHOULD BE FORMATTED TO
 * RUN THIS TEST.
 *
 * NOTE: THIS TEST HAS BEEN DEVELOPED TO WORK WITH CHIP VERSIONS C5505, C5515
 * AND C5517. MAKE SURE THAT PROPER CHIP VERSION MACRO IS DEFINED IN THE FILE
 * c55xx_csl\inc\csl_general.h.
 *
 * \subsection MMC10y    TEST PROCEDURE:
 *  @li Insert formatted "SD" card into the MMC/SD socket(J9) on the C5505/C5515 EVM
 *  or J16 on C5517 EVM
 *  @li Open the CCS and connect the target (C5505/C5515/C5517 EVM)
 *  @li Open the project "CSL_MMCSD_SdCardFSExample_Out.pjt" and build it
 *  @li Load the program on to the target
 *  @li Set the PLL frequency to 12.288MHz
 *  @li Run the program and observe the test result
 *  @li Repeat the test at PLL frequencies 40, 60, 75 and 100MHz
 *  @li Repeat the test in Release mode
 *
 * \subsection MMC10z    TEST RESULT:
 *  @li All the CSL APIs should return success
 *  @li Data in the read and write buffers should match.
 *  @li File created should be accessible from a windows PC using card reader.
 *
 * ============================================================================
 */

/* ============================================================================
 * Revision History
 * ================
 * 10-Jun-2009 Created
 * 08-Feb-2010 Modified to configure the clock rate depending on CPU clock
 * 19-Jul-2012 Added C5517 compatibility
 * 09-Mar-2016 Update the header
 * ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <csl_general.h>
#include "chk_mmc.h"
#include "csl_pll.h"
#include "ata_ext_func.h"
#include "csl_sysctrl.h"

#include "soc.h"
#include "cslr.h"
/* CSL include files */
#include "csl_gpio.h"
#include "csl_i2s.h"
#include "csl_dma.h"
#include "csl_intc.h"

#include "pll_control.h"
#include "codec_aic3254.h"
#include "IdleLoop.h"


#include "wave_parser.h"
#include "wave_parser.c"

#include <csl_mmcsd.h>
#include <csl_mmcsd_ataIf.h>
#include <csl_types.h>


#ifdef INSTANCE2_I2S
#define I2S_INSTANCE    ( I2S_INSTANCE2 )
#define DMA_CHAN_TX_L      ( CSL_DMA_CHAN4 )
#define DMA_CHAN_TX_R      ( CSL_DMA_CHAN5 )
#define DMA_CHAN_RX_L      ( CSL_DMA_CHAN6 )
#define DMA_CHAN_RX_R      ( CSL_DMA_CHAN7 )

#define I2S2_SRGR          *(volatile ioport Uint16*)(0x2A04)
#define I2S2_ICMR          *(volatile ioport Uint16*)(0x2A14)
#define I2S2_CR            *(volatile ioport Uint16*)(0x2A00)

#endif



#define CSL_MMCSD_ATA_BUF_SIZE     (512u)

/*
 * Macro to define SD card clock maximum value in KHz. Depending on the clock
 * at which CPU is running, SD clock will be configured to the possible
 * value that is nearest to the value defined by this macro. SD clock will
 * be configured to a value less than or equal to but not greater
 * than the value defined by this macro. Changing this macro value
 * will automatically change the memory clock divider value.
 * memory clock will be generated from the system clock based on equation
 *
 * memory clock = (system clock) / (2 * (CLKRT + 1)
 *    - memory clock is clock for the memory card
 *    - system clock is clock at which CPU us running
 *    - CLKRT is value of clock rate configured in clock control register
 *
 * As per this equation memory clock that can be generated is always less than
 * or equal to half of the system clock value. Value of 'CLKRT' can range
 * from 0 to 255. Maximum and minimum memory clock values that can be generated
 * at a particular CPU frequency are limited by the minimum and maximum value
 * of the memory clock rate (CLKRT).
 *
 * NOTE: SD SPECIFICATION DEFINED MAXIMUM CLOCK VALUE IS 25MHZ FOR NORMAL SD
 * CARDS AND IS 50MHZ FOR HIGH SPEED CARDS. VALUE OF THIS MACRO SHOULD NOT
 * CROSS THIS MAXIMUM LIMITS.
 */
#define CSL_SD_CLOCK_MAX_KHZ      (20000u)

void extractWaveInfo(waveHeader *header, Uint16 *data);
int checkWaveHeader(waveHeader *header);
AtaState    gstrAtaDrive;
AtaState    *gpstrAtaDrive = &gstrAtaDrive;

AtaFile     strAtaFile;
AtaFile     *pAtaFile = &strAtaFile;

#pragma DATA_ALIGN(AtaWrBuf ,4);
AtaUint16   AtaWrBuf[256];
AtaMMCState  gstrAtaMMCState;
AtaMMCState  *gpstrAtaMMCState = &gstrAtaMMCState;

/* CSL MMCSD Data structures */
CSL_MMCControllerObj    pMmcsdContObj;
CSL_MmcsdHandle         mmcsdHandle;
CSL_MMCCardObj          mmcCardObj;
CSL_MMCCardIdObj        sdCardIdObj;
CSL_MMCCardCsdObj       sdCardCsdObj;

/* CSL DMA data structures */
CSL_DMA_Handle        dmaWrHandle;
CSL_DMA_Handle        dmaRdHandle;
CSL_DMA_ChannelObj    dmaWrChanObj;
CSL_DMA_ChannelObj    dmaRdChanObj;
CSL_DMA_Handle        dmaHandle;

Uint16    gMmcWriteBuf[CSL_MMCSD_ATA_BUF_SIZE];
Uint16    gMmcReadBuf[CSL_MMCSD_ATA_BUF_SIZE];


extern void VECSTART(void); // defined in vector table
CSL_IRQ_Dispatch     dispatchTable;

CSL_GpioObj gGpioObj;
GPIO_Handle hGpio;

CSL_I2sHandle hI2s;

CSL_DMA_Handle dmaLeftTxHandle;
CSL_DMA_Handle dmaRightTxHandle;
CSL_DMA_ChannelObj dmaObj0, dmaObj1, dmaObj2, dmaObj3;
volatile Uint16 dmaTxFrameCount = 0, dmaRxFrameCount=0;

CSL_DMA_Handle dmaLeftRxHandle;
CSL_DMA_Handle dmaRightRxHandle;



/* Ping/pong buffers */
#pragma DATA_ALIGN(i2sDmaWriteBufLeft, 8);
Uint32 i2sDmaWriteBufLeft[I2S_DMA_BUF_LEN];  // left Tx write ping/pong buffer
#pragma DATA_ALIGN(i2sDmaWriteBufRight, 8);
Uint32 i2sDmaWriteBufRight[I2S_DMA_BUF_LEN]; // right Tx write ping/pong buffe
#pragma DATA_ALIGN(i2sDmaReadBufLeft, 8);
Uint32 i2sDmaReadBufLeft[I2S_DMA_BUF_LEN];  // left Rx read ping/pong buffer
#pragma DATA_ALIGN(i2sDmaReadBufRight, 8);
Uint32 i2sDmaReadBufRight[I2S_DMA_BUF_LEN]; // right Rx read ping/pong buffer




CSL_Status DeviceInit(void);

// Initializes DMA
CSL_Status DmaInit(void);

// GPIO initialization
CSL_Status GpioInit(Uint32 ioDir, Uint32 intEn, Uint32 intEdg);

// I2S and DMA initialization
CSL_Status I2sDmaInit(void);

// User defined algorithm
void UserAlgorithm(void);

// Put CPU in idle
void UserIdle(void);


#ifndef CHIP_C5517
// USB LDO Switch
void UsbLdoSwitch(Uint16 mode);
#endif

// DMA ISR
interrupt void DmaIsr(void);

CSL_Status ioExpander_Setup(void);
CSL_Status ioExpander_Read(Uint16 port, Uint16 pin, Uint16 *rValue);
CSL_Status ioExpander_Write(Uint16 port, Uint16 pin, Uint16 value);

#define CSL_MMCSD_ATAFS_DISKTYPE   (0)

/**
 *  \brief  Function to initialize and configure SD card
 *
 *  \param  opMode   - Operating Mode of MMCSD; POLL/DMA
 *
 *  \return Test result
 */
CSL_Status configSdCard (CSL_MMCSDOpMode    opMode);

/**
 *  \brief  Function to test CSL MMCSD-ATAFS interface
 *
 *  \param  none
 *
 *  \return none
 */
void mmcFileTest(void);

/**
 *  \brief  Function to configure file system and perform
 *          read/write operations
 *
 *  \param  fileName - Name of the file to be created
 *
 *  \return Test result
 */
AtaError mmcConfigFs(char    *fileName);

/**
 *  \brief    Function to calculate the memory clock rate
 *
 * This function computes the memory clock rate value depending on the
 * CPU frequency. This value is used as clock divider value for
 * calling the API MMC_sendOpCond(). Value of the clock rate computed
 * by this function will change depending on the system clock value
 * and SD card maximum clock value defined by macro 'CSL_SD_CLOCK_MAX_KHZ'.
 * Minimum clock rate value returned by this function is 0 and
 * maximum clock rate value returned by this function is 255.
 * Clock derived using the clock rate returned by this API will be
 * the nearest value to 'CSL_SD_CLOCK_MAX_KHZ'.
 *
 *  \param    none
 *
 *  \return   MMC clock rate value
 */
Uint16 computeClkRate(void);

/**
 *  \brief  Main function
 *
 *  \param  none
 *
 *  \return none
 */
void main(void)
{

    CSL_Status status;
    mmcFileTest();

        CSL_SYSCTRL_REGS->PCGCR1 = 0x0000;
        CSL_SYSCTRL_REGS->PCGCR2 = 0x0000;

        printf("I2S Idle Loop Audio Playback Example\n");
        printf("This Example will continuously Pump PC lineout to the ");
        printf("Audio Output using the Codec\n\n");

        printf("Please connect the Headphone to the Audio Output (Headphone) ");
        printf("Jack\n\n");

        // Initialize DSP
        status = DeviceInit();
        if (status != CSL_SOK)
        {
            printf("ERROR: Unable to initialize DSP\n");
            exit(EXIT_FAILURE);
        }

#ifdef CHIP_C5517
    status = ioExpander_Setup();
    if (status != CSL_SOK)
    {
        printf("ERROR: ioExpander_Setup Failed\n");
        exit(EXIT_FAILURE);
    }

    status = ioExpander_Write(0, 2, 1);// SEL_I2C_S0 = 1
    status = ioExpander_Write(0, 3, 0);// SEL_I2C_S1 = 0
    /* Configure SPI2 mux for AIC3204-2 */
    status = ioExpander_Write(0, 5, 1);// SPI_I2S2_S0 = 1
    status = ioExpander_Write(0, 6, 1); // SPI_I2S2_S1 = 1
    /* Release AIC3204 reset */
    status = ioExpander_Write(0, 0, 0);// AIC_RST = 0
    if (status != CSL_SOK)
    {
        printf("ERROR: ioExpander_Write Failed\n");
        exit(EXIT_FAILURE);
    }
#endif

    // Initialize DMA
       status = DmaInit();
       if (status != CSL_SOK)
       {
           printf("ERROR: Unable to initialize DMA\n");
           exit(EXIT_FAILURE);
       }

   #ifndef CHIP_C5517
       /* GPIO10 for AIC3204 reset */
       Uint32 gpioIoDir = (((Uint32)CSL_GPIO_DIR_OUTPUT)<<CSL_GPIO_PIN10);
       status = GpioInit(gpioIoDir, 0x00000000, 0x00000000);
       if (status != CSL_SOK)
       {
           printf("ERROR: Unable to initialize GPIO\n");
           exit(1);
       }
   #endif

       // Initialize I2S with DMA
       status = I2sDmaInit();
       if (status != CSL_SOK)
       {
           printf("ERROR: Unable to initialize I2S and DMA\n");
           exit(1);
       }

       /* Intialize AIC3204 codec */
       status = AIC3254_init(48000, 48000, PLL_MHZ);
       if (status != CSL_SOK)
       {
           printf("ERROR: Unable to initialize AIC3204\n");
           exit(1);
       }



       /* Set CPUI bit in ICR */
       //*(volatile ioport Uint16 *)(0x0001) |= 0x000F;
       /* Set CPUI, DPORTI, XPORTI, and IPORTI in ICR */
       *(volatile ioport Uint16 *)(0x0001) |= 0x016F;

       /* Enable global interrupt */
       IRQ_globalEnable();

       /* Enable I2S */
   #ifdef INSTANCE0_I2S
       CSL_I2S0_REGS->I2SSCTRL |= 0x8000;
   #else
       CSL_I2S2_REGS->I2SSCTRL |= 0x8000;
   #endif
       printf("Pumping PC lineout to the HP Output Started!!\n");

       while (1)
       {
           /* Perform your algorithm here */
           UserAlgorithm();

           /* Set CPU to Idle */
           //UserIdle();
       }

}




CSL_Status DeviceInit(void)
{
    Uint16 prcr;
    CSL_Status status;

    // Set up dispatch table
    status = IRQ_init(&dispatchTable, 0);
    if (status != CSL_SOK)
    {
        //printf("IRQ_init() fail, status=%d\n", status);
        return status;
    }

    // Disable global interrupts
    IRQ_globalDisable();

    // Disable all the interrupts
    IRQ_disableAll();

    // Clear any pending interrupts
    IRQ_clearAll();

    // Set the interrupt vector table address
    status = IRQ_setVecs((Uint32)&VECSTART);
    if (status != CSL_SOK)
    {
        //printf("IRQ_setVecs() fail, status=%d\n", status);
        return status;
    }

    // Reset all peripherals
    CSL_SYSCTRL_REGS->PSRCR = 0x0020;
    CSL_SYSCTRL_REGS->PRCR = 0x00BF;
    do
    {
        prcr = CSL_SYSCTRL_REGS->PRCR;
    } while (prcr != 0);

#ifndef CHIP_C5517

    // Set PLL output frequency
    // Note: desired frequency must be allowed for core voltage setting
    status = pll_sample(PLL_MHZ);
    if (status != CSL_SOK)
    {
        //printf("pll_sample() fail, status=%d\n", status);
        return status;
    }

    // Turn off USB LDO
    UsbLdoSwitch(0);

#endif

    return CSL_SOK;
}


#ifndef CHIP_C5517
void UsbLdoSwitch(Uint16 mode)
{
    Uint16 pcgcr2;

    pcgcr2 = CSL_SYSCTRL_REGS->PCGCR2; // save PCGCR2

    /* Enable the Analog Register only */
    CSL_SYSCTRL_REGS->PCGCR2 &= ~(0x0040);

#if (defined(CHIP_C5517))
    if (mode == 0)
    {
        /* Disable USB LDO (clear bit 0) */
        CSL_LDO_REGS->LDOCTRL &= 0xFFFE;
    }

    if (mode == 1)
    {
        /* Enable USB LDO (set bit 0) */
        CSL_LDO_REGS->LDOCTRL |= 0x0001;
    }
#else
    if (mode == 0)
    {
        /* Disable USB LDO (clear bit 0) */
        CSL_SAR_REGS->USBLDOCNTL &= 0xFFFE;
    }

    if (mode == 1)
    {
        /* Enable USB LDO (set bit 0) */
        CSL_SAR_REGS->USBLDOCNTL |= 0x0001;
    }
#endif

    CSL_SYSCTRL_REGS->PCGCR2 = pcgcr2; // restore PCGCR2
}

#endif//CHIP_C5517


CSL_Status DmaInit(void)
{
    Uint16 ifrValue;
    CSL_Status status;

    // Disable DMA interrupt
    IRQ_disable(DMA_EVENT);

    // Clear DMA interrupt
    IRQ_clear(DMA_EVENT);

    // Disable DMA interrupts
    CSL_SYSCTRL_REGS->DMAIER = 0x0000;

    // Clear pending DMA interrupts
    ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
    CSL_SYSCTRL_REGS->DMAIFR |= ifrValue;

    // Plug in DMA ISR
    IRQ_plug(DMA_EVENT, &DmaIsr);

    // DMA initialization
    status = DMA_init();
    if (status != CSL_SOK)
    {
        //printf("DMA_init() fail, status=%d\n", status);
        return status;
    }

    // Enable DMA interrupt
    IRQ_enable(DMA_EVENT);

    return CSL_SOK;
}

#ifndef CHIP_C5517
CSL_Status GpioInit(
    Uint32 ioDir,
    Uint32 intEn,
    Uint32 intEdg
)
{
    CSL_Status status;
    CSL_GpioConfig config;

    /* Open GPIO module */
    hGpio = GPIO_open(&gGpioObj, &status);
    if ((hGpio == NULL) || (status != CSL_SOK))
    {
        return status;
    }

    /* Reset GPIO module */
    status = GPIO_reset(hGpio);
    if (status != CSL_SOK)
    {
        return status;
    }

    /* Configure GPIO module */
    config.GPIODIRL = ioDir & 0xFFFF;
    config.GPIODIRH = ioDir >> 16;
    config.GPIOINTENAL = intEn & 0xFFFF;
    config.GPIOINTENAH = intEn >> 16;
    config.GPIOINTTRIGL = intEdg & 0xFFFF;
    config.GPIOINTTRIGH = intEdg >> 16;
    status = GPIO_config(hGpio, &config);
    if (status != CSL_SOK)
    {
        return status;
    }

    return CSL_SOK;
}
#endif


CSL_Status I2sDmaInit(void)
{
    I2S_Config hwConfig;
    CSL_DMA_Config dmaConfig;
    CSL_Status status;

    /* DMA engine initialization */
    /* Open the device with instance 0/2 */
    /*(AIC3204-1 is connected to I2S0 on C5517 EVM) */
    /*(AIC3204-2 is connected to I2S2 on C5517 EVM) */
    hI2s = I2S_open(I2S_INSTANCE, DMA_POLLED, I2S_CHAN_STEREO);
    if(NULL == hI2s)
    {
        status = CSL_ESYS_FAIL;
        return (status);
    }
    else
    {
        printf ("I2S2 Module Instance opened successfully\n");
    }


    if (I2S_INSTANCE0 == I2S_INSTANCE)
    {
        status = SYS_setEBSR(CSL_EBSR_FIELD_SP0MODE,
                             CSL_EBSR_SP0MODE_1);
    }
    else
    {
        status = SYS_setEBSR(CSL_EBSR_FIELD_PPMODE,
                             CSL_EBSR_PPMODE_6);
    }

#ifndef CHIP_C5517
    // Serial Port mode 1 (I2S1 and GP[11:10]).
    //*(volatile ioport Uint16*)(CSL_SYSCTRL_REGS) |=  0x0800;
    status = SYS_setEBSR(CSL_EBSR_FIELD_SP1MODE,
                            CSL_EBSR_SP1MODE_2);
#endif
    if(CSL_SOK != status)
    {
        printf("SYS_setEBSR failed\n");
        return (status);
    }

    /* Set the value for the configure structure */
    hwConfig.dataFormat     = I2S_DATAFORMAT_LJUST;
    hwConfig.dataType       = I2S_STEREO_ENABLE;
    hwConfig.loopBackMode   = I2S_LOOPBACK_DISABLE;
    hwConfig.fsPol          = I2S_FSPOL_LOW;
    hwConfig.clkPol         = I2S_RISING_EDGE;//I2S_FALLING_EDGE;
    hwConfig.datadelay      = I2S_DATADELAY_ONEBIT;
    hwConfig.datapack       = I2S_DATAPACK_DISABLE;
    hwConfig.signext        = I2S_SIGNEXT_DISABLE;
    hwConfig.wordLen        = I2S_WORDLEN_16;
    hwConfig.i2sMode        = I2S_SLAVE;
    hwConfig.clkDiv         = I2S_CLKDIV2; // don't care for slave mode
    hwConfig.fsDiv          = I2S_FSDIV32; // don't care for slave mode
    hwConfig.FError         = I2S_FSERROR_DISABLE;
    hwConfig.OuError        = I2S_OUERROR_DISABLE;

    /* Configure hardware registers */
    status = I2S_setup(hI2s, &hwConfig);
    if(status != CSL_SOK)
    {
        return (status);
    }
    else
    {
        printf ("I2S2 Module Configured successfully\n");
    }

    /* Configure DMA channel 0 for I2S left channel write*/
    dmaConfig.pingPongMode  = CSL_DMA_PING_PONG_DISABLE;
    dmaConfig.autoMode      = CSL_DMA_AUTORELOAD_ENABLE;
    dmaConfig.burstLen      = CSL_DMA_TXBURST_1WORD;
    dmaConfig.trigger       = CSL_DMA_EVENT_TRIGGER;
#ifdef INSTANCE0_I2S
    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S0_TX;
#endif
#ifdef INSTANCE2_I2S
    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S2_TX;
#endif

    dmaConfig.dmaInt        = CSL_DMA_INTERRUPT_ENABLE;
    dmaConfig.chanDir       = CSL_DMA_WRITE;
    dmaConfig.trfType       = CSL_DMA_TRANSFER_IO_MEMORY;
    dmaConfig.dataLen       = NUM_SAMP_PER_MS*NUM_MS_PER_FRAME*4*2; // two frames

#ifdef INSTANCE0_I2S
#if (defined(CHIP_C5517))
    dmaConfig.destAddr      = (Uint32)&CSL_I2S0_REGS->I2STXLTL;
#else
    dmaConfig.destAddr      = (Uint32)&CSL_I2S0_REGS->I2STXLT0;
#endif
#endif
#ifdef INSTANCE2_I2S
#if (defined(CHIP_C5517))
    dmaConfig.destAddr      = (Uint32)&CSL_I2S2_REGS->I2STXLTL;
#else
    dmaConfig.destAddr      = (Uint32)&CSL_I2S2_REGS->I2STXLT0;
#endif
#endif
    dmaConfig.srcAddr       = (Uint32)i2sDmaWriteBufLeft;

    /* Open DMA ch0 for I2S left channel write*/
    dmaLeftTxHandle = DMA_open(DMA_CHAN_TX_L, &dmaObj0,&status);
    if (dmaLeftTxHandle == NULL)
    {
        printf("DMA_open CH0 Failed \n");
        dmaLeftTxHandle = NULL;
    }

    /* Configure DMA channe0 */
    status = DMA_config(dmaLeftTxHandle, &dmaConfig);
    if (status != CSL_SOK)
    {
        printf("DMA_config CH0 Failed \n");
        dmaLeftTxHandle = NULL;
    }

    /* Configure DMA ch1 for I2S right channel write*/
    dmaConfig.pingPongMode = CSL_DMA_PING_PONG_DISABLE;
    dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_ENABLE;
    dmaConfig.burstLen     = CSL_DMA_TXBURST_1WORD;
    dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;
#ifdef INSTANCE0_I2S
    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S0_TX;
#endif
#ifdef INSTANCE2_I2S
    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S2_TX;
#endif
    dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_ENABLE;
    dmaConfig.chanDir      = CSL_DMA_WRITE;
    dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
    dmaConfig.dataLen      = NUM_SAMP_PER_MS*NUM_MS_PER_FRAME*4*2;  // two frames

#ifdef INSTANCE0_I2S
#if (defined(CHIP_C5517))
    dmaConfig.destAddr     = (Uint32)&CSL_I2S0_REGS->I2STXRTL;
#else
    dmaConfig.destAddr     = (Uint32)&CSL_I2S0_REGS->I2STXRT0;
#endif
#endif
#ifdef INSTANCE2_I2S
#if (defined(CHIP_C5517))
    dmaConfig.destAddr     = (Uint32)&CSL_I2S2_REGS->I2STXRTL;
#else
    dmaConfig.destAddr     = (Uint32)&CSL_I2S2_REGS->I2STXRT0;
#endif
#endif


    dmaConfig.srcAddr      = (Uint32)i2sDmaWriteBufRight;

    /* Open DMA ch1 for I2S right channel write*/
    dmaRightTxHandle = DMA_open(DMA_CHAN_TX_R, &dmaObj1,&status);
    if (dmaRightTxHandle == NULL)
    {
        printf("DMA_open CH1 Failed \n");
        dmaRightTxHandle = NULL;
    }

    /* Configure DMA channel1*/
    status = DMA_config(dmaRightTxHandle, &dmaConfig);
    if (status != CSL_SOK)
    {
        printf("DMA_config CH1 Failed \n");
        dmaRightTxHandle = NULL;
    }

    /* Configure DMA channel 2 for I2S left channel read */
    dmaConfig.pingPongMode  = CSL_DMA_PING_PONG_DISABLE;
    dmaConfig.autoMode      = CSL_DMA_AUTORELOAD_ENABLE;
    dmaConfig.burstLen      = CSL_DMA_TXBURST_1WORD;
    dmaConfig.trigger       = CSL_DMA_EVENT_TRIGGER;
#ifdef INSTANCE0_I2S
    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S0_RX;
#endif
#ifdef INSTANCE2_I2S
    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S2_RX;
#endif
    dmaConfig.dmaInt        = CSL_DMA_INTERRUPT_ENABLE;
    dmaConfig.chanDir       = CSL_DMA_READ;
    dmaConfig.trfType       = CSL_DMA_TRANSFER_IO_MEMORY;
    dmaConfig.dataLen       = NUM_SAMP_PER_MS*NUM_MS_PER_FRAME*4*2; // two frames

#ifdef INSTANCE0_I2S
#if (defined(CHIP_C5517))
    dmaConfig.srcAddr      = (Uint32)&CSL_I2S0_REGS->I2SRXLTL;
#else
    dmaConfig.srcAddr      = (Uint32)&CSL_I2S0_REGS->I2SRXLT0;
#endif
#endif
#ifdef INSTANCE2_I2S
#if (defined(CHIP_C5517))
    dmaConfig.srcAddr      = (Uint32)&CSL_I2S2_REGS->I2SRXLTL;
#else
    dmaConfig.srcAddr      = (Uint32)&CSL_I2S2_REGS->I2SRXLT0;
#endif
#endif

    dmaConfig.destAddr       = (Uint32)i2sDmaReadBufLeft;

    /* Open DMA ch2 for I2S left channel read */
    dmaLeftRxHandle = DMA_open(DMA_CHAN_RX_L, &dmaObj2,&status);
    if (dmaLeftRxHandle == NULL)
    {
        printf("DMA_open CH2 Failed \n");
        dmaLeftRxHandle = NULL;
    }

    /* Configure DMA channel2 */
    status = DMA_config(dmaLeftRxHandle, &dmaConfig);
    if (status != CSL_SOK)
    {
        printf("DMA_config CH2 Failed \n");
        dmaLeftRxHandle = NULL;
    }

    /* Configure DMA ch3 for I2S right channel read */
    dmaConfig.pingPongMode = CSL_DMA_PING_PONG_DISABLE;
    dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_ENABLE;
    dmaConfig.burstLen     = CSL_DMA_TXBURST_1WORD;
    dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;
#ifdef INSTANCE0_I2S
    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S0_RX;
#endif

#ifdef INSTANCE2_I2S
    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S2_RX;
#endif
    dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_ENABLE;
    dmaConfig.chanDir      = CSL_DMA_READ;
    dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
    dmaConfig.dataLen      = NUM_SAMP_PER_MS*NUM_MS_PER_FRAME*4*2;  // two frames

#ifdef INSTANCE0_I2S
#if (defined(CHIP_C5517))
    dmaConfig.srcAddr     = (Uint32)&CSL_I2S0_REGS->I2SRXRTL;
#else
    dmaConfig.srcAddr     = (Uint32)&CSL_I2S0_REGS->I2SRXRT0;
#endif
#endif

#ifdef INSTANCE2_I2S
#if (defined(CHIP_C5517))
    dmaConfig.srcAddr     = (Uint32)&CSL_I2S2_REGS->I2SRXRTL;
#else
    dmaConfig.srcAddr     = (Uint32)&CSL_I2S2_REGS->I2SRXRT0;
#endif
#endif

    dmaConfig.destAddr      = (Uint32)i2sDmaReadBufRight;

    /* Open DMA ch3 for I2S right channel read */
    dmaRightRxHandle = DMA_open(DMA_CHAN_RX_R, &dmaObj3,&status);
    if (dmaRightRxHandle == NULL)
    {
        printf("DMA_open CH3 Failed \n");
        dmaRightRxHandle = NULL;
    }

    /* Configure DMA channel */
    status = DMA_config(dmaRightRxHandle, &dmaConfig);
    if (status != CSL_SOK)
    {
        printf("DMA_config CH3 Failed \n");
        dmaRightRxHandle = NULL;
    }

    return CSL_SOK;
}


/* User defined algorithm */
void UserAlgorithm(void)
{
    Uint16 i;
    Uint16 status=0;
    if(!dmaRxFrameCount)
    {
        /* Start left Rx DMA */
        status = DMA_start(dmaLeftRxHandle);
        if (status != CSL_SOK)
        {
            printf("I2S Dma Left Rx Failed!!\n");
            exit(EXIT_FAILURE);
        }


        /* Start right Rx DMA */
        status = DMA_start(dmaRightRxHandle);
        if (status != CSL_SOK)
        {
            printf("I2S Dma Right Rx Failed!!\n");
            exit(EXIT_FAILURE);
        }

    }


    if (dmaRxFrameCount >= 2)
    {
        dmaRxFrameCount=0;
        DMA_stop(dmaLeftRxHandle);
        DMA_stop(dmaRightRxHandle);

        for (i=0; i<I2S_DMA_BUF_LEN; i++)
        {

            i2sDmaWriteBufLeft[i]  = i2sDmaReadBufLeft[i];
            i2sDmaWriteBufRight[i] = i2sDmaReadBufRight[i];
        }

        /* --- Insert algorithm here --- */

    }


    if(!dmaTxFrameCount)
    {
        /* Start left Tx DMA */
        status = DMA_start(dmaLeftTxHandle);
        if (status != CSL_SOK)
        {
            printf("I2S Dma Left Tx Failed!!\n");
            exit(EXIT_FAILURE);
        }

        /* Start right Tx DMA */
        status = DMA_start(dmaRightTxHandle);
        if (status != CSL_SOK)
        {
            printf("I2S Dma Right Tx Failed!!\n");
            exit(EXIT_FAILURE);
        }

    }


    /* Clear DMA frame count */
    if(dmaTxFrameCount>=2)
    {
        dmaTxFrameCount = 0;
        DMA_stop(dmaLeftTxHandle);
        DMA_stop(dmaRightTxHandle);
    }

}


volatile Uint32 dmaIntCount = 0;
// DMA ISR
interrupt void DmaIsr(void)
{
    volatile Uint16 ifrValue;

    /* Clear the DMA interrupt */
    ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
    CSL_SYSCTRL_REGS->DMAIFR |= ifrValue;

    /* Check for DMA1 CH0 transfer completion */
#ifdef INSTANCE0_I2S
    if (ifrValue & 1)
    {
        dmaTxFrameCount++;
    }
#endif

#ifdef INSTANCE2_I2S
    if (ifrValue & (1<<4))
    {
        dmaTxFrameCount++;
    }
#endif


    /* Check for DMA1 CH1 transfer completion */
#ifdef INSTANCE0_I2S
    if (ifrValue & (1<<1))
    {
        dmaTxFrameCount++;
    }
#endif

#ifdef INSTANCE2_I2S
    if (ifrValue & (1<<5))
    {
        dmaTxFrameCount++;
    }
#endif

    /* Check for DMA1 CH2 transfer completion */
#ifdef INSTANCE0_I2S
    if (ifrValue & (1<<2))
    {
        dmaRxFrameCount++;
    }
#endif
#ifdef INSTANCE2_I2S
    if (ifrValue & (1<<6))
    {
        dmaRxFrameCount++;
    }
#endif

    /* Check for DMA1 CH3 transfer completion */
#ifdef INSTANCE0_I2S
    if (ifrValue & (1<<3))
    {
        dmaRxFrameCount++;
    }
#endif
#ifdef INSTANCE2_I2S

    if (ifrValue & (1<<7))
    {
        dmaRxFrameCount++;
    }
#endif

    dmaIntCount++;
}


/**
 *  \brief  Function to test CSL MMCSD-ATAFS interface
 *
 *  \param  none
 *
 *  \return Test result
 */
   /////INSTRUMENTATION FOR BATCH TESTING -- Part 1 --
   /////  Define PaSs_StAtE variable for catching errors as program executes.
   /////  Define PaSs flag for holding final pass/fail result at program completion.
        volatile Int16 PaSs_StAtE = 0x0001; // Init to 1. Reset to 0 at any monitored execution error.
        volatile Int16 PaSs = 0x0000; // Init to 0.  Updated later with PaSs_StAtE when and if
   /////                                  program flow reaches expected exit point(s).
   /////
void mmcFileTest(void)
{
    CSL_Status    status;
    AtaError      ataStatus;
    Bool          testFailed;

    testFailed = FALSE;

    printf("MMCSD-ATAFS TESTS!\n\n");

//  printf("MMCSD-ATAFS POLL MODE TEST!\n\n");
//
//  status = configSdCard(CSL_MMCSD_OPMODE_POLLED);
//  if(status != CSL_SOK)
//  {
//      testFailed = TRUE;
//   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --
//   /////  Reseting PaSs_StAtE to 0 if error detected here.
//        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
//   /////
//      printf("SD card initialization Failed\n");
//      printf("\nMMCSD-ATAFS POLL MODE TEST FAILED!!\n");
//  }
//  else
//  {
//      printf("SD card initialization Successful\n");
//      ataStatus = mmcConfigFs("polled");
//      if(ataStatus != ATA_ERROR_NONE)
//      {
//          testFailed = TRUE;
//   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --
//   /////  Reseting PaSs_StAtE to 0 if error detected here.
//        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
//   /////
//          printf("\nMMCSD-ATAFS POLL MODE TEST FAILED!!\n");
//      }
//      else
//      {
//          printf("\nMMCSD-ATAFS POLL MODE TEST PASSED!!\n");
//      }
//  }

    printf("\n\n\nMMCSD-ATAFS DMA MODE TEST!\n\n");

    status = configSdCard(CSL_MMCSD_OPMODE_DMA);
    if(status != CSL_SOK)
    {
        testFailed = TRUE;
   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --
   /////  Reseting PaSs_StAtE to 0 if error detected here.
        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
   /////
        printf("SD card initialization Failed\n");
        printf("\nMMCSD-ATAFS DMA MODE TEST FAILED!!\n");
    }
    else
    {
        printf("SD card initialization Successful\n");
        ataStatus = mmcConfigFs("sample");
        if(ataStatus != ATA_ERROR_NONE)
        {
            testFailed = TRUE;
   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --
   /////  Reseting PaSs_StAtE to 0 if error detected here.
        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
   /////
            printf("\nMMCSD-ATAFS DMA MODE TEST FAILED!!\n");
        }
        else
        {
            printf("\nMMCSD-ATAFS DMA MODE TEST PASSED!!\n");
        }
    }

   /////INSTRUMENTATION FOR BATCH TESTING -- Part 3 --
   /////  At program exit, copy "PaSs_StAtE" into "PaSs".
        PaSs = PaSs_StAtE; //If flow gets here, override PaSs' initial 0 with
   /////                   // pass/fail value determined during program execution.
   /////  Note:  Program should next exit to C$$EXIT and halt, where DSS, under
   /////   control of a host PC script, will read and record the PaSs' value.
   /////

    if (testFailed == TRUE)
    {
        printf("\n\nMMCSD-ATAFS TESTS FAILED!!\n\n");
        //exit(EXIT_FAILURE);
    }
    else
    {
        printf("\n\nMMCSD-ATAFS TESTS PASSED!!\n\n");
        //exit(EXIT_SUCCESS);
    }
}

/**
 *  \brief  Function to configure file system and perform
 *          read/write operations
 *
 *  \param  fileName - Name of the file to be created
 *
 *  \return Test result
 */
AtaError mmcConfigFs(char    *fileName)
{
//    Uint16        index;
    AtaError      ata_error;
    waveHeader    header;
    unsigned int diskType;

    ata_error = ATA_ERROR_NONE;

//    for(index = 0; index < CSL_MMCSD_ATA_BUF_SIZE; index++)
//    {
//        gMmcWriteBuf[index] = 0x4142;
//      AtaWrBuf[index] = 0x4344;
//        gMmcReadBuf[index]  = 0x0;
//    }

    /* Call init function initialize ATA state structure */
    gpstrAtaDrive->AtaInitAtaMediaState = (AtaError (*)(void *))MMC_initState;
    gpstrAtaMMCState->hMmcSd = mmcsdHandle;
    gpstrAtaDrive->pAtaMediaState = gpstrAtaMMCState;
    gpstrAtaDrive->AtaInitAtaMediaState(gpstrAtaDrive);

    /* Set the temp write buffer */
    gpstrAtaDrive->_AtaWriteBuffer = AtaWrBuf;


    /* For partitioned disk, 'diskType' should be 0
       and for unpartiotioned disk, it should be 1
     */
     /* chk_mmc() function is used to check the partition type of
        SD card.
        ATA_systemInit() function needs to be called
        with 'diskType' set to 0 before calling chk_mmc().
        chk_mmc() function will check whether the disk is partitioned
        or unpartitioned. If disk is not partitioned it will change the
        'diskType' value to 1 otherwise it will not change the diskType value.
        After calling chk_mmc() if 'diskType' is not '0' , It means that
        the SD card is not partitioned and ATA_systemInit() needs to be
        called with 'diskType' value modified by chk_mmc() function */

    diskType = CSL_MMCSD_ATAFS_DISKTYPE;
    /* Call ATA_systemInit() to intialize some values whcih are
      used by chk_mmc() function */
    ata_error = ATA_systemInit(gpstrAtaDrive, diskType);

    chk_mmc(gpstrAtaDrive, &diskType);
    if(diskType != CSL_MMCSD_ATAFS_DISKTYPE)
    {
        ata_error = ATA_systemInit(gpstrAtaDrive, diskType);
        if(ata_error != ATA_ERROR_NONE)
        {
            printf("ATA_systemInit Failed\n");
            printf("Format the SD card\n");
            return(ata_error);
        }
    }

    printf("\nATA File System Initialization successful\n");

    /* Find the first file available */
    ata_error =  ATA_fileInit(gpstrAtaDrive, pAtaFile);
    if(ata_error) {
        printf("ATA_fileInit error (0x%x)\n", ata_error);
        return(ata_error);
    }

#if 0
    /* Set the file name */
    ATA_setFileName(pAtaFile, fileName, "wav");

    ata_error = ATA_create(pAtaFile);
#else
    ata_error = ATA_fopen(pAtaFile, fileName, "wav");
#endif
    if(ata_error != ATA_ERROR_NONE)
    {
        printf("ATA_fopen Failed\n");
        return(ata_error);
    }
    else
    {
        printf("\nFile Creation/Open on SD card is Successful\n");
    }

    /* Write data to the file */
//    ata_error = ATA_write(pAtaFile, gMmcWriteBuf, CSL_MMCSD_ATA_BUF_SIZE);
//    if(ata_error != ATA_ERROR_NONE)
//    {
//      printf("ATA_write Failed\n");
//        return(ata_error);
//    }
//    else
//    {
//      printf("\nWriting Data to the file on SD card successful\n");
//  }

    /* Reset the file pointer to the beginning */
    ATA_seek (pAtaFile, 0);

    /* Read the data from the file in little endian mode */
    ata_error = ATA_read(pAtaFile,gMmcReadBuf, sizeof(header));
    if(ata_error != ATA_ERROR_NONE)
    {
        printf("ATA_read Failed\n");
        return(ata_error);
    }
    else
    {
        printf("\nReading Data from the file on SD card successful\n");
    }

    extractWaveInfo(&header, gMmcReadBuf);


//    if(checkWaveHeader(&header))
//        {
//            printf("Invalid WAV file\n");
//           // return (ata_error);
//        }

        printf("WAV file details:\n");
        printf("Chunk ID: %08X\n", header.chunkID);
        printf("Chunk Size: %u\n", header.chunkSize);
        printf("Format: %08X\n", header.format);
        printf("Audio Format: %u\n", header.audioFormat);
        printf("Number of Channels: %u\n", header.numChannels);
        printf("Sample Rate: %u\n", header.sampleRate);
        printf("Byte Rate: %u\n", header.byteRate);
        printf("Block Align: %u\n", header.blockAlign);
        printf("Bits Per Sample: %u\n", header.bitsPerSample);
        printf("Subchunk2 Size: %u\n", header.subchunk2Size);


        size_t totalBytesRead = 0;
           size_t fileSize = header.subchunk2Size; // Size of audio data
           while (totalBytesRead < fileSize)
           {
               size_t bytesToRead = sizeof(gMmcReadBuf);
               if (fileSize - totalBytesRead < bytesToRead)
               {
                   bytesToRead = fileSize - totalBytesRead;
               }

               ata_error = ATA_read(pAtaFile, gMmcReadBuf, bytesToRead);
               if (ata_error != ATA_ERROR_NONE)
               {
                   printf("ATA_read Failed\n");
                   return(ata_error);
               }
               int i;
               for (i = 0; i < bytesToRead / 2; i++)  // Each Uint16 is 2 bytes
                     {
                         printf("%04X ", gMmcReadBuf[i]);
                         if ((i + 1) % 16 == 0) // Print a newline every 16 values
                         {
                             printf("\n");
                         }
                     }

               // Process the read data (e.g., store in a buffer, play audio, etc.)
               totalBytesRead += bytesToRead;

               if (totalBytesRead >= 256) // Print only the first 256 bytes
                       {
                           break;
                       }
           }



    /* Close the file */
    ata_error = ATA_close(pAtaFile);
    if(ata_error != ATA_ERROR_NONE)
    {
        printf("ATA_close Failed\n");
        return(ata_error);
    }

    /* Compare the data read and data written */
//    for(index = 0; index < CSL_MMCSD_ATA_BUF_SIZE; index++)
//    {
//        if(gMmcWriteBuf[index] != gMmcReadBuf[index])
//        {
//            ata_error = 1;
//            printf("\nMMCSD Read and Write Buffers do not Match\n");
//            break;
//        }
//    }
//
//    if(ata_error == 0)
//    {
//        printf("\nMMCSD Read and Write Buffers Match\n");
//    }

    return(ata_error);
}

/**
 *  \brief  Function to initialize and configure SD card
 *
 *  \param  opMode   - Operating Mode of MMCSD; POLL/DMA
 *
 *  \return Test result
 */
CSL_Status configSdCard (CSL_MMCSDOpMode    opMode)
{
    CSL_Status     status;
    Uint16         actCard;
    Uint16         clockDiv;
    Uint16         rca;
    CSL_CardType   cardType;

    cardType  = CSL_CARD_NONE;

    /* Get the clock divider value for the current CPU frequency */
    clockDiv = computeClkRate();

    /* Initialize MMCSD CSL module */
    status = MMC_init();

    status = SYS_setEBSR(CSL_EBSR_FIELD_SP0MODE,
                         CSL_EBSR_SP0MODE_0);
    status |= SYS_setEBSR(CSL_EBSR_FIELD_SP1MODE,
                         CSL_EBSR_SP1MODE_0);
    if(CSL_SOK != status)
    {
        printf("SYS_setEBSR failed\n");
        return (status);
    }

    /* Open MMCSD CSL module */
#ifdef C5515_EZDSP
    mmcsdHandle = MMC_open(&pMmcsdContObj, CSL_MMCSD1_INST,
                           opMode, &status);
#else
    mmcsdHandle = MMC_open(&pMmcsdContObj, CSL_MMCSD0_INST,
                           opMode, &status);
#endif
    if(mmcsdHandle == NULL)
    {
        printf("MMC_open Failed\n");
        return (status);
    }

    /* Configure the DMA in case of operating mode is set to DMA */
    if(opMode == CSL_MMCSD_OPMODE_DMA)
    {
        /* Initialize Dma */
        status = DMA_init();
        if (status != CSL_SOK)
        {
            printf("DMA_init Failed!\n");
            return(status);
        }

        /* Open Dma channel for MMCSD write */
        dmaWrHandle = DMA_open(CSL_DMA_CHAN0, &dmaWrChanObj, &status);
        if((dmaWrHandle == NULL) || (status != CSL_SOK))
        {
            printf("DMA_open for MMCSD Write Failed!\n");
            return(status);
        }

        /* Open Dma channel for MMCSD read */
        dmaRdHandle = DMA_open(CSL_DMA_CHAN1, &dmaRdChanObj, &status);
        if((dmaRdHandle == NULL) || (status != CSL_SOK))
        {
            printf("DMA_open for MMCSD Read Failed!\n");
            return(status);
        }

        /* Set the DMA handle for MMC read */
        status = MMC_setDmaHandle(mmcsdHandle, dmaWrHandle, dmaRdHandle);
        if(status != CSL_SOK)
        {
            printf("API: MMC_setDmaHandle for MMCSD Failed\n");
            return(status);
        }
    }

    /* Reset the SD card */
    status = MMC_sendGoIdle(mmcsdHandle);
    if(status != CSL_SOK)
    {
        printf("MMC_sendGoIdle Failed\n");
        return (status);
    }

    /* Check for the card */
    status = MMC_selectCard(mmcsdHandle, &mmcCardObj);
    if((status == CSL_ESYS_BADHANDLE) ||
       (status == CSL_ESYS_INVPARAMS))
    {
        printf("MMC_selectCard Failed\n");
        return (status);
    }

    /* Verify whether the SD card is detected or not */
    if(mmcCardObj.cardType == CSL_MMC_CARD)
    {
        printf("MMC Card Detected!\n\n");
        cardType = CSL_MMC_CARD;
#if 0
        cardAddr = (sectCount)*(CSL_MMCSD_BLOCK_LENGTH);
#endif
        /* Send the MMC card identification Data */
        status = MMC_sendAllCID(mmcsdHandle, &sdCardIdObj);
        if(status != CSL_SOK)
        {
            printf("API: MMC_sendAllCID Failed\n");
            return(status);
        }

        /* Set the MMC Relative Card Address */
        status = MMC_setRca(mmcsdHandle, &mmcCardObj, 0x0001);
        if(status != CSL_SOK)
        {
            printf("API: MMC_setRca Failed\n");
            return(status);
        }

        /* Read the MMC Card Specific Data */
        status = MMC_getCardCsd(mmcsdHandle, &sdCardCsdObj);
        if(status != CSL_SOK)
        {
            printf("API: MMC_getCardCsd Failed\n");
            return(status);
        }

        /* Get the clock divider value for the current CPU frequency */
        clockDiv = computeClkRate();
    }
    else if(mmcCardObj.cardType == CSL_SD_CARD)
    {
        printf("SD Card detected\n");
        cardType = CSL_SD_CARD;

        /* Check if the card is high capacity card */
        if(mmcsdHandle->cardObj->sdHcDetected == TRUE)
        {
            printf("SD card is High Capacity Card\n");
            printf("Memory Access will use Block Addressing\n");
        }
        else
        {
            printf("SD card is Standard Capacity Card\n");
            printf("Memory Access will use Byte Addressing\n");
        }

        /* Set the init clock */
        status = MMC_sendOpCond(mmcsdHandle, 70);
        if(status != CSL_SOK)
        {
            printf("MMC_sendOpCond Failed\n");
            return (status);
        }

        /* Send the card identification Data */
        status = SD_sendAllCID(mmcsdHandle, &sdCardIdObj);
        if(status != CSL_SOK)
        {
            printf("SD_sendAllCID Failed\n");
            return (status);
        }

        /* Set the Relative Card Address */
        status = SD_sendRca(mmcsdHandle, &mmcCardObj, &rca);
        if(status != CSL_SOK)
        {
            printf("SD_sendRca Failed\n");
            return (status);
        }

        /* Read the SD Card Specific Data */
        status = SD_getCardCsd(mmcsdHandle, &sdCardCsdObj);
        if(status != CSL_SOK)
        {
            printf("SD_getCardCsd Failed\n");
            return (status);
        }
    }
    else
    {
        if(mmcCardObj.cardType == CSL_CARD_NONE)
        {
            printf("No Card detected\n");
        }
        else
        {
            printf("SD Card not detected\n");
        }
        printf("Please Insert SD Card\n");
        return(CSL_ESYS_FAIL);
    }

    /* Set the card type in internal data structures */
    status = MMC_setCardType(&mmcCardObj, cardType);
    if(status != CSL_SOK)
    {
        printf("MMC_setCardType Failed\n");
        return (status);
    }

    /* Set the card pointer in internal data structures */
    status = MMC_setCardPtr(mmcsdHandle, &mmcCardObj);
    if(status != CSL_SOK)
    {
        printf("MMC_setCardPtr Failed\n");
        return (status);
    }

    /* Get the number of cards */
    status = MMC_getNumberOfCards(mmcsdHandle, &actCard);
    if(status != CSL_SOK)
    {
        printf("MMC_getNumberOfCards Failed\n");
        return (status);
    }

    /* Set clock for read-write access */
    status = MMC_sendOpCond(mmcsdHandle, clockDiv);
    if(status != CSL_SOK)
    {
        printf("MMC_sendOpCond Failed\n");
        return (status);
    }

    /* Set Endian mode for read and write operations */
    status = MMC_setEndianMode(mmcsdHandle, CSL_MMCSD_ENDIAN_LITTLE,
                               CSL_MMCSD_ENDIAN_LITTLE);
    if(status != CSL_SOK)
    {
        printf("MMC_setEndianMode Failed\n");
        return(status);
    }

    /* Set block length for the memory card
     * For high capacity cards setting the block length will have
     * no effect
     */
    status = MMC_setBlockLength(mmcsdHandle, CSL_MMCSD_BLOCK_LENGTH);
    if(status != CSL_SOK)
    {
        printf("MMC_setBlockLength Failed\n");
        return(status);
    }
#if 0
    for(looper = 0; looper < 256; looper++)
    {
        gMmcWriteBuf[looper] = 0xABCD;
    }

    /* Write data to the MMC card */
    status = MMC_write(mmcsdHandle, 0, 512,
                          gMmcWriteBuf);
    if(status != CSL_SOK)
    {
        printf("API: MMC_write Failed\n");
        return(status);
    }
    else
    {
        printf("API: MMC_write Successful\n");
    }

    /* Read data from the MMC card */
    status = MMC_read(mmcsdHandle, 0, 512,
                         gMmcReadBuf);
    if(status != CSL_SOK)
    {
        printf("API: MMC_read Failed\n");
        return(status);
    }
    else
    {
        printf("API: MMC_read Successful\n");
    }

//    /* Compare the MMC read and write buffers */
//    for(looper = 0; looper < 256; ++looper)
//    {
//        if(gMmcReadBuf[looper] != gMmcWriteBuf[looper])
//        {
//            printf("\nBuffer Miss Matched at Position %d\n",looper);
//            return(CSL_ESYS_FAIL);
//        }
//    }
#endif
    return (status);
}

/**
 *  \brief    Function to calculate the memory clock rate
 *
 * This function computes the memory clock rate value depending on the
 * CPU frequency. This value is used as clock divider value for
 * calling the API MMC_sendOpCond(). Value of the clock rate computed
 * by this function will change depending on the system clock value
 * and MMC maximum clock value defined by macro 'CSL_SD_CLOCK_MAX_KHZ'.
 * Minimum clock rate value returned by this function is 0 and
 * maximum clock rate value returned by this function is 255.
 * Clock derived using the clock rate returned by this API will be
 * the nearest value to 'CSL_SD_CLOCK_MAX_KHZ'.
 *
 *  \param    none
 *
 *  \return   MMC clock rate value
 */
Uint16 computeClkRate(void)
{
    Uint32    sysClock;
    Uint32    remainder;
    Uint32    memMaxClk;
    Uint16    clkRate;

    sysClock  = 0;
    remainder = 0;
    memMaxClk = CSL_SD_CLOCK_MAX_KHZ;
    clkRate   = 0;

    /* Get the clock value at which CPU is running */
    sysClock = getSysClk();

    if (sysClock > memMaxClk)
    {
        if (memMaxClk != 0)
        {
            clkRate   = sysClock / memMaxClk;
            remainder = sysClock % memMaxClk;

            /*
             * If the remainder is not equal to 0, increment clock rate to make
             * sure that memory clock value is less than the value of
             * 'CSL_SD_CLOCK_MAX_KHZ'.
             */
            if (remainder != 0)
            {
                clkRate++;
            }

            /*
             * memory clock divider '(2 * (CLKRT + 1)' will always
             * be an even number. Increment the clock rate in case of
             * clock rate is not an even number
             */
            if (clkRate%2 != 0)
            {
                clkRate++;
            }

            /*
             * AT this point 'clkRate' holds the value of (2 * (CLKRT + 1).
             * Get the value of CLKRT.
             */
            clkRate = clkRate/2;
            clkRate = clkRate - 1;

            /*
             * If the clock rate is more than the maximum allowed clock rate
             * set the value of clock rate to maximum value.
             * This case will become true only when the value of
             * 'CSL_SD_CLOCK_MAX_KHZ' is less than the minimum possible
             * memory clock that can be generated at a particular CPU clock.
             *
             */
            if (clkRate > CSL_MMC_MAX_CLOCK_RATE)
            {
                clkRate = CSL_MMC_MAX_CLOCK_RATE;
            }
        }
        else
        {
            clkRate = CSL_MMC_MAX_CLOCK_RATE;
        }
    }

    return (clkRate);
}

My challenge is determining how to properly assign input for the AIC3254 audio codec and configure the gmmcreadbuf function from the MMCSD example for use with the I2S audio codec DMA.

Both examples aim to read a WAV file and play the audio through a headset.

Waveheader information

  • Hi Kishor,

    In your code (audio in to audio out loopback):

    for (i=0; i<I2S_DMA_BUF_LEN; i++)
    {

        i2sDmaWriteBufLeft[i] = i2sDmaReadBufLeft[i];
        i2sDmaWriteBufRight[i] = i2sDmaReadBufRight[i];
    }

    should be changed to (if the WAV file is mono) 

    for (i=0; i<I2S_DMA_BUF_LEN; i++)
    {

        i2sDmaWriteBufLeft[i] = gMmcReadBuf[i];
        i2sDmaWriteBufRight[i] = gMmcReadBuf[i];
    }

    If the WAV file stereo, the audio samples are interleaved, left, right, ...

    for (i=0; i<I2S_DMA_BUF_LEN; i++)
    {

        i2sDmaWriteBufLeft[i] = gMmcReadBuf[i*2];
        i2sDmaWriteBufRight[i] = gMmcReadBuf[i*2+1];
    }

    Best regards,

    Ming