Quantcast
Channel: Processors forum - Recent Threads
Viewing all articles
Browse latest Browse all 17527

Can't get EDMA to work on UART1 of OMAP L138

$
0
0

Hi Guys, 

I'm struggling in getting the EDMA to work on UART1 on the OMAPL138. I have an example (from Starterware) running, using UART2 and this is going fine. Now I'd like to change this example to use UART1. I have modified the code to use UART1 but transmitting data does not succeed (no interrupt is thrown when finished, it doesn't reach the edmaCompletionHandler nor the edmaErrorHandler). I am not sure whether I configured everything properly. Note that UART1 is working well when just using the ISR without EDMA. My code is given below.

So basic questions:

- Is it possible at all to use EDMA for UART1?

- What am I doing wrong?

 

I'm starting to become pretty frustrated, I hope you guys can help me out.

Thanks in advance!

 

Best regards,

Jeroen

/**
 * \file  uartEcho.c
 *
 * \brief This is a sample application file which invokes some APIs
 *        from the EDMA3 device abstraction layer as well as UART 
 *        device abstraction layer to perform configuration, and 
 *        transfer of data between UART and CPU RAM by the 
 *        use of EDMA3
 */

/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 
*
*  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.
*/

#include "psc.h"
#include "uart.h"
#include "edma.h"
#include "string.h"
#include "hw_types.h"
#include "uartStdio.h"
#include "evmOMAPL138.h"
#include "interrupt.h"
#include "edma_event.h"
#include "soc_OMAPL138.h"
#include "hw_psc_OMAPL138.h"

/****************************************************************************/
/*                      INTERNAL MACRO DEFINITIONS                          */
/****************************************************************************/
#define UART_RBR_THR_REG           ((0x01D0D000u) + (0u))

#define MAX_ACNT                   1
#define MAX_CCNT                   1

#define RX_BUFFER_SIZE             50

/* EDMA3 Event queue number. */
#define EVT_QUEUE_NUM	           0


#define BAUD_RATE 115200


/****************************************************************************/
/*                      LOCAL FUNCTION PROTOTYPES                           */
/****************************************************************************/
static void UartTransmitData(unsigned int tccNum, unsigned int chNum,
                             volatile char *buffer, unsigned int buffLength);

/* Callback Function Declaration*/
static void (*cb_Fxn[EDMA3_NUM_TCC]) (unsigned int tcc, unsigned int status);
static void UartReceiveData(unsigned int tccNum, unsigned int chNum, 
                            volatile char *buffer);
static void callback(unsigned int tccNum, unsigned int status);
static void ConfigureIntEDMA3(void);
static void Edma3ComplHandlerIsr(void);
static void Edma3CCErrHandlerIsr(void);
static void EDMA3Initialize(void);
static void SetupInt(void);

/****************************************************************************/
/*                      GLOBAL VARIABLES                                    */
/****************************************************************************/
volatile unsigned int flag = 0;

/****************************************************************************/
/*                   LOCAL FUNCTION DEFINITIONS                             */
/****************************************************************************/

/*
** Main function.
*/


static void initUART1(unsigned int

/**
 * \file  uartEcho.c
 *
 * \brief This is a sample application file which invokes some APIs
 *        from the EDMA3 device abstraction layer as well as UART
 *        device abstraction layer to perform configuration, and
 *        transfer of data between UART and CPU RAM by the
 *        use of EDMA3
 */

/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
*  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.
*/

#include "psc.h"
#include "uart.h"
#include "edma.h"
#include "string.h"
#include "hw_types.h"
#include "uartStdio.h"
#include "evmOMAPL138.h"
#include "interrupt.h"
#include "edma_event.h"
#include "soc_OMAPL138.h"
#include "hw_psc_OMAPL138.h"

/****************************************************************************/
/*                      INTERNAL MACRO DEFINITIONS                          */
/****************************************************************************/
#define UART_RBR_THR_REG           ((0x01D0D000u) + (0u))

#define MAX_ACNT                   1
#define MAX_CCNT                   1

#define RX_BUFFER_SIZE             50

/* EDMA3 Event queue number. */
#define EVT_QUEUE_NUM            0


#define BAUD_RATE 115200


/****************************************************************************/
/*                      LOCAL FUNCTION PROTOTYPES                           */
/****************************************************************************/
static void UartTransmitData(unsigned int tccNum, unsigned int chNum,
                             volatile char *buffer, unsigned int buffLength);

/* Callback Function Declaration*/
static void (*cb_Fxn[EDMA3_NUM_TCC]) (unsigned int tcc, unsigned int status);
static void UartReceiveData(unsigned int tccNum, unsigned int chNum,
                            volatile char *buffer);
static void callback(unsigned int tccNum, unsigned int status);
static void ConfigureIntEDMA3(void);
static void Edma3ComplHandlerIsr(void);
static void Edma3CCErrHandlerIsr(void);
static void EDMA3Initialize(void);
static void SetupInt(void);

/****************************************************************************/
/*                      GLOBAL VARIABLES                                    */
/****************************************************************************/
volatile unsigned int flag = 0;

/****************************************************************************/
/*                   LOCAL FUNCTION DEFINITIONS                             */
/****************************************************************************/

/*
** Main function.
*/


static void initUART1(unsigned int rxTrigLevel)
{

 /* Enabling the PSC for UARTs.*/
  PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART1, PSC_POWERDOMAIN_ALWAYS_ON,
  PSC_MDCTL_NEXT_ENABLE);

 /* Setup PINMUX */ 
  UARTPinMuxSetup(1, FALSE);


  /* Enabling the transmitter and receiver*/ 
  UARTEnable(SOC_UART_1_REGS);


  /* Configuring the UART parameters*/   
   UARTConfigSetExpClk(SOC_UART_1_REGS, SOC_UART_1_MODULE_FREQ,
   BAUD_RATE, UART_WORDL_8BITS,
   UART_OVER_SAMP_RATE_16);


  /* Enabling the FIFO and flushing the Tx and Rx FIFOs.*/  
   UARTFIFOEnable(SOC_UART_1_REGS);


   /* Setting the UART Receiver Trigger Level*/ 
 UARTFIFOLevelSet(SOC_UART_1_REGS, rxTrigLevel);


}

int main(void)
{
    volatile char enter[] = {170, 7, 0, 42, 1, 50, 239};
    volatile char buffer[RX_BUFFER_SIZE];
    unsigned int buffLength = 0;

    /* Initialize EDMA3 Controller */
    EDMA3Initialize();

    /* Initialize UARTs */
 initUART1(UART_RX_TRIG_LEVEL_1);

    /* Request DMA Channel and TCC for UART Transmit*/
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
          EDMA3_CHA_UART1_TX, EDMA3_CHA_UART1_TX,
                            EVT_QUEUE_NUM);

    /* Registering Callback Function for TX*/
    cb_Fxn[EDMA3_CHA_UART1_TX] = &callback;

    /* Request DMA Channel and TCC for UART Receive */   
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                            EDMA3_CHA_UART1_RX, EDMA3_CHA_UART1_RX,
                            EVT_QUEUE_NUM);

    /* Registering Callback Function for RX*/
    cb_Fxn[EDMA3_CHA_UART1_RX] = &callback;


    /* Used for bCnt */
    buffLength = strlen((const char *) enter);

    /* Transmit Data for Enter Message */   
    UartTransmitData(EDMA3_CHA_UART1_TX, EDMA3_CHA_UART1_TX,
                         enter, buffLength);

    /* Enabling UART in DMA Mode*/   
    UARTDMAEnable(SOC_UART_1_REGS, UART_RX_TRIG_LEVEL_1 |  \
                                       UART_DMAMODE |          \
                                       UART_FIFO_MODE );

    /* Wait for control to return from call-back function */
    while(0 == flag);
    flag = 0;

    /* Receive Data for Input */
    UartReceiveData(EDMA3_CHA_UART1_RX, EDMA3_CHA_UART1_RX, buffer);

    /* Enabling UART in DMA Mode*/
    UARTDMAEnable(SOC_UART_1_REGS, UART_RX_TRIG_LEVEL_1 | \
                                          UART_DMAMODE |         \
                                          UART_FIFO_MODE );


    /* Wait for return from callback */    
    while(0 == flag);
    flag = 0;
   
    /* Transmit Data for Entered value */
    UartTransmitData(EDMA3_CHA_UART1_TX, EDMA3_CHA_UART1_TX,
                             buffer, RX_BUFFER_SIZE);

    /* Enabling UART in DMA Mode*/
 UARTDMAEnable(SOC_UART_1_REGS, UART_RX_TRIG_LEVEL_1 |  \
                                           UART_DMAMODE |           \
                                           UART_FIFO_MODE );

    /* Wait for return from callback */
    while(0 == flag);
    flag = 0;

    /* Free EDMA3 Channels for TX and RX */
    EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                         EDMA3_CHA_UART1_TX, EDMA3_TRIG_MODE_EVENT,
                         EDMA3_CHA_UART1_TX, EVT_QUEUE_NUM);

    EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                          EDMA3_CHA_UART1_RX, EDMA3_TRIG_MODE_EVENT,
                          EDMA3_CHA_UART1_RX, EVT_QUEUE_NUM);

    while(1);

}

/*
** This function is used to set the PaRAM entries in EDMA3 for the Transmit Channel
** of UART. EDMA3 Enable Transfer is also called within this API.
*/

static void UartTransmitData(unsigned int tccNum, unsigned int chNum,
                             volatile char *buffer, unsigned int buffLength)
{
    EDMA3CCPaRAMEntry paramSet;

    /* Fill the PaRAM Set with transfer specific information */
    paramSet.srcAddr = (unsigned int) buffer;
    paramSet.destAddr = UART_RBR_THR_REG;
    paramSet.aCnt = MAX_ACNT;
    paramSet.bCnt = (unsigned short) buffLength;
    paramSet.cCnt = MAX_CCNT;

    /* The src index should increment for every byte being transferred. */
    paramSet.srcBIdx = (short) 1u;

    /* The dst index should not be increment since it is a h/w register*/
    paramSet.destBIdx = (short) 0u;
 
    /* A sync Transfer Mode */
    paramSet.srcCIdx = (short) 0u;
    paramSet.destCIdx = (short) 0u;
    paramSet.linkAddr = (unsigned short)0xFFFFu;
    paramSet.bCntReload = (unsigned short)0u;
    paramSet.opt = 0x00000000u;
    paramSet.opt |= (EDMA3CC_OPT_DAM );
    paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
    paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);

    /* Now write the PaRAM Set */
    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, &paramSet);

    /* Enable EDMA Transfer */
    EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_EVENT);
}

/*
** This function is used to set the PARAM SET of EDMA3 for the Receive Channel
** of UART. EDMA3 Enable Transfer is also called within this API.
*/

static void UartReceiveData(unsigned int tccNum, unsigned int chNum,
                            volatile char *buffer)
{
    EDMA3CCPaRAMEntry paramSet;

    /* Fill the PaRAM Set with transfer specific information */
    paramSet.srcAddr = UART_RBR_THR_REG;
    paramSet.destAddr = (unsigned int) buffer;
    paramSet.aCnt = MAX_ACNT;
    paramSet.bCnt = RX_BUFFER_SIZE;
    paramSet.cCnt = MAX_CCNT;

    /* The src index should not be increment since it is a h/w register*/
    paramSet.srcBIdx = 0;
    /* The dest index should incremented for every byte */
    paramSet.destBIdx = 1;

    /* A sync Transfer Mode */
    paramSet.srcCIdx = 0;
    paramSet.destCIdx = 0;
    paramSet.linkAddr = (unsigned short)0xFFFFu;
    paramSet.bCntReload = 0;
    paramSet.opt = 0x00000000u;   
    paramSet.opt |= ((EDMA3CC_OPT_SAM) << EDMA3CC_OPT_SAM_SHIFT);
    paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
    paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);

    /* Now write the PaRAM Set */
    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, &paramSet);

    /* Enable EDMA Transfer */
    EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_EVENT);
}

/* Function used to Initialize EDMA3 */
static void EDMA3Initialize(void)
{

  /* Enabling the PSC for EDMA3CC_0.*/
 PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON,
     PSC_MDCTL_NEXT_ENABLE);

 /* Enabling the PSC for EDMA3TC_0.*/
 PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON,
    PSC_MDCTL_NEXT_ENABLE);

 /* Initialization of EDMA3 */
    EDMA3Init(SOC_EDMA30CC_0_REGS, EVT_QUEUE_NUM);
  
    /*
    ** Enable AINTC to handle interuppts. Also enable IRQ interuppt in
    ** ARM processor.
    */
    SetupInt();

    /* Register EDMA3 Interrupts */
    ConfigureIntEDMA3();
}

/* Function used to Setup ARM Interuppt Controller */
static void SetupInt(void)
{
#ifdef _TMS320C6X
 // Initialize the DSP Interrupt controller
 IntDSPINTCInit();

 // Enable DSP interrupts globally
 IntGlobalEnable();
#else
    /*Initialize the ARM Interrupt Controller(AINTC). */
    IntAINTCInit();

    /* Enable IRQ in CPSR.*/    
    IntMasterIRQEnable();

    /* Enable the interrupts in GER of AINTC.*/
    IntGlobalEnable();

    /* Enable the interrupts in HIER of AINTC.*/
    IntIRQEnable();
#endif
}

/* EDMA3 Completion Handler */
static void edma3ComplHandler(unsigned int baseAdd, unsigned int regionNum)
{
    volatile unsigned int pendingIrqs;
    volatile unsigned int isIPR = 0;

    unsigned int indexl;
    unsigned int Cnt = 0;
    indexl = 1;
   
#ifdef _TMS320C6X
    IntEventClear(SYS_INT_EDMA3_0_CC0_INT1);
#else
    IntSystemStatusClear(SYS_INT_CCINT0);
#endif
    isIPR = HWREG(baseAdd + EDMA3CC_S_IPR(regionNum));
    if(isIPR)
    {
        while ((Cnt < EDMA3CC_COMPL_HANDLER_RETRY_COUNT)&& (indexl != 0u))
        {
            indexl = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_S_IPR(regionNum));
            while (pendingIrqs)
            {
                if((pendingIrqs & 1u) == TRUE)
                {
                    /**
                    * If the user has not given any callback function
                    * while requesting the TCC, its TCC specific bit
                    * in the IPR register will NOT be cleared.
                    */
                    /* here write to ICR to clear the corresponding IPR bits */
                    HWREG(baseAdd + EDMA3CC_S_ICR(regionNum)) = (1u << indexl);

                    (*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE);
                }
                ++indexl;
                pendingIrqs >>= 1u;
            }
            Cnt++;
        }
    }
}

static void Edma3ComplHandlerIsr(void)
{
#ifdef _TMS320C6X
 // Invoke Completion Handler ISR
 edma3ComplHandler(SOC_EDMA30CC_0_REGS, 1);
#else
    /* Invoke Completion Handler ISR */
    edma3ComplHandler(SOC_EDMA30CC_0_REGS, 0);
#endif
}

/* EDMA3 Error Handler */
static void edma3CCErrHandler(unsigned int baseAdd)
{
    volatile unsigned int pendingIrqs = 0;
    unsigned int regionNum = 0;
    unsigned int evtqueNum = 0; 
    unsigned int index = 1;
    unsigned int Cnt = 0;
   
#ifdef _TMS320C6X
    IntEventClear(SYS_INT_EDMA3_0_CC0_ERRINT);
#else
    IntSystemStatusClear(SYS_INT_CCERRINT);
#endif

    if((HWREG(baseAdd + EDMA3CC_EMR) != 0 ) || \
       (HWREG(baseAdd + EDMA3CC_QEMR) != 0) || \
       (HWREG(baseAdd + EDMA3CC_CCERR) != 0))
    {
        /* Loop for EDMA3CC_ERR_HANDLER_RETRY_COUNT number of time, breaks
           when no pending interrupt is found */
        while ((Cnt < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (index != 0u))
        {
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_EMR);
            while (pendingIrqs)
            {
                /*Process all the pending interrupts*/
                if((pendingIrqs & 1u)==TRUE)
                {
                    /* Write to EMCR to clear the corresponding EMR bits.*/
                    HWREG(baseAdd + EDMA3CC_EMCR) = (1u<<index);
                    /*Clear any SER*/
                    HWREG(baseAdd + EDMA3CC_S_SECR(regionNum)) = (1u<<index);
                }
                ++index;
                pendingIrqs >>= 1u;
            }
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_QEMR);
            while (pendingIrqs)
            {
                /*Process all the pending interrupts*/
                if((pendingIrqs & 1u)==TRUE)
                {
                    /* Here write to QEMCR to clear the corresponding QEMR bits*/
                    HWREG(baseAdd + EDMA3CC_QEMCR) = (1u<<index);
                    /*Clear any QSER*/
                    HWREG(baseAdd + EDMA3CC_S_QSECR(0)) = (1u<<index);
                }
                ++index;
                pendingIrqs >>= 1u;
            }
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_CCERR);
    if (pendingIrqs != 0u)
    {
        /* Process all the pending CC error interrupts. */
        /* Queue threshold error for different event queues.*/
        for (evtqueNum = 0u; evtqueNum < EDMA3_0_NUM_EVTQUE; evtqueNum++)
        {
            if((pendingIrqs & (1u << evtqueNum)) != 0u)
            {
                /* Clear the error interrupt. */
                HWREG(baseAdd + EDMA3CC_CCERRCLR) = (1u << evtqueNum);
            }
         }

         /* Transfer completion code error. */
         if ((pendingIrqs & (1 << EDMA3CC_CCERR_TCCERR_SHIFT)) != 0u)
         {
             HWREG(baseAdd + EDMA3CC_CCERRCLR) = \
                  (0x01u << EDMA3CC_CCERR_TCCERR_SHIFT);
         }
         ++index;
    }
    Cnt++;
        }
    }
}

static void Edma3CCErrHandlerIsr()
{
    /* Invoke CC Error Handler ISR */
    edma3CCErrHandler(SOC_EDMA30CC_0_REGS);
}

/* Function to register EDMA3 Interuppts */
static void ConfigureIntEDMA3(void)
{
    /* Register Interrupts Here */

//Note: ARM is used
#ifdef _TMS320C6X
 IntRegister(C674X_MASK_INT4, Edma3ComplHandlerIsr);
 IntRegister(C674X_MASK_INT5, Edma3CCErrHandlerIsr);

 IntEventMap(C674X_MASK_INT4, SYS_INT_EDMA3_0_CC0_INT1);
 IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_0_CC0_ERRINT);

 IntEnable(C674X_MASK_INT4);
 IntEnable(C674X_MASK_INT5);
#else
    IntRegister(SYS_INT_CCINT0, Edma3ComplHandlerIsr);

 IntChannelSet(SYS_INT_CCINT0, 2);
 //Should be IntChannelSet(SYS_INT_CCINT0, 1); or IntChannelSet(SYS_INT_CCINT0, 4);?

    IntSystemEnable(SYS_INT_CCINT0);

    IntRegister(SYS_INT_CCERRINT, Edma3CCErrHandlerIsr);

 IntChannelSet(SYS_INT_CCERRINT, 2);
 //Should be IntChannelSet(SYS_INT_CCINT0, 1); or IntChannelSet(SYS_INT_CCINT0, 4);?

    IntSystemEnable(SYS_INT_CCERRINT);
#endif
}


/*
** This function is used as a callback from EDMA3 Completion Handler.
** UART in DMA Mode is Disabled over here.
*/
static void callback(unsigned int tccNum, unsigned int status)
{   
 UARTDMADisable(SOC_UART_1_REGS, (UART_RX_TRIG_LEVEL_1 | UART_FIFO_MODE)); 
    flag = 1;
}

/********************************* End of file ******************************/

, unsigned int rxTrigLevel)
{

	/* Enabling the PSC for UARTs.*/
	 PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART1, PSC_POWERDOMAIN_ALWAYS_ON,
	 PSC_MDCTL_NEXT_ENABLE);

	/* Setup PINMUX */	 
	 UARTPinMuxSetup(1, FALSE);


	 /* Enabling the transmitter and receiver*/	 
	 UARTEnable(SOC_UART_1_REGS);


	 /* Configuring the UART parameters*/ 	  
	  UARTConfigSetExpClk(SOC_UART_1_REGS, SOC_UART_1_MODULE_FREQ,
	  BAUD_RATE, UART_WORDL_8BITS,
	  UART_OVER_SAMP_RATE_16);


  /* Enabling the FIFO and flushing the Tx and Rx FIFOs.*/   
   UARTFIFOEnable(SOC_UART_1_REGS);


   /* Setting the UART Receiver Trigger Level*/	
	UARTFIFOLevelSet(SOC_UART_1_REGS, rxTrigLevel);


}



int main(void)
{
    volatile char enter[] = {170, 7, 0, 42, 1, 50, 239};
    volatile char buffer[RX_BUFFER_SIZE];
    unsigned int buffLength = 0;

    /* Initialize EDMA3 Controller */
    EDMA3Initialize();

    /* Initialize UARTs */
	initUART1(BAUD_RATE, UART_RX_TRIG_LEVEL_1);

    /* Request DMA Channel and TCC for UART Transmit*/
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
        		EDMA3_CHA_UART1_TX, EDMA3_CHA_UART1_TX,
                            EVT_QUEUE_NUM);

    /* Registering Callback Function for TX*/
    cb_Fxn[EDMA3_CHA_UART1_TX] = &callback;

    /* Request DMA Channel and TCC for UART Receive */    
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                            EDMA3_CHA_UART1_RX, EDMA3_CHA_UART1_RX,
                            EVT_QUEUE_NUM);

    /* Registering Callback Function for RX*/ 
    cb_Fxn[EDMA3_CHA_UART1_RX] = &callback;


    /* Used for bCnt */
    buffLength = strlen((const char *) enter); 

    /* Transmit Data for Enter Message */    
    UartTransmitData(EDMA3_CHA_UART1_TX, EDMA3_CHA_UART1_TX,
                         enter, buffLength);

    /* Enabling UART in DMA Mode*/    
    UARTDMAEnable(SOC_UART_1_REGS, UART_RX_TRIG_LEVEL_1 |  \
                                       UART_DMAMODE |          \
                                       UART_FIFO_MODE );

    /* Wait for control to return from call-back function */
    while(0 == flag); 
    flag = 0;

    /* Receive Data for Input */
    UartReceiveData(EDMA3_CHA_UART1_RX, EDMA3_CHA_UART1_RX, buffer);

    /* Enabling UART in DMA Mode*/
    UARTDMAEnable(SOC_UART_1_REGS, UART_RX_TRIG_LEVEL_1 | \
                                          UART_DMAMODE |         \
                                          UART_FIFO_MODE );


    /* Wait for return from callback */     
    while(0 == flag);
    flag = 0;
    
    /* Transmit Data for Entered value */
    UartTransmitData(EDMA3_CHA_UART1_TX, EDMA3_CHA_UART1_TX,
                             buffer, RX_BUFFER_SIZE);

    /* Enabling UART in DMA Mode*/
	UARTDMAEnable(SOC_UART_1_REGS, UART_RX_TRIG_LEVEL_1 |  \
                                           UART_DMAMODE |           \
                                           UART_FIFO_MODE );

    /* Wait for return from callback */
    while(0 == flag); 
    flag = 0;

    /* Free EDMA3 Channels for TX and RX */
    EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                         EDMA3_CHA_UART1_TX, EDMA3_TRIG_MODE_EVENT,
                         EDMA3_CHA_UART1_TX, EVT_QUEUE_NUM);

    EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                          EDMA3_CHA_UART1_RX, EDMA3_TRIG_MODE_EVENT,
                          EDMA3_CHA_UART1_RX, EVT_QUEUE_NUM);

    while(1);

}

/*
** This function is used to set the PaRAM entries in EDMA3 for the Transmit Channel
** of UART. EDMA3 Enable Transfer is also called within this API.
*/

static void UartTransmitData(unsigned int tccNum, unsigned int chNum,
                             volatile char *buffer, unsigned int buffLength)
{
    EDMA3CCPaRAMEntry paramSet;

    /* Fill the PaRAM Set with transfer specific information */
    paramSet.srcAddr = (unsigned int) buffer;
    paramSet.destAddr = UART_RBR_THR_REG;
    paramSet.aCnt = MAX_ACNT;
    paramSet.bCnt = (unsigned short) buffLength;
    paramSet.cCnt = MAX_CCNT;

    /* The src index should increment for every byte being transferred. */
    paramSet.srcBIdx = (short) 1u;

    /* The dst index should not be increment since it is a h/w register*/
    paramSet.destBIdx = (short) 0u;
  
    /* A sync Transfer Mode */
    paramSet.srcCIdx = (short) 0u;
    paramSet.destCIdx = (short) 0u;
    paramSet.linkAddr = (unsigned short)0xFFFFu;
    paramSet.bCntReload = (unsigned short)0u;
    paramSet.opt = 0x00000000u;
    paramSet.opt |= (EDMA3CC_OPT_DAM );
    paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
    paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);

    /* Now write the PaRAM Set */
    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, &paramSet);

    /* Enable EDMA Transfer */
    EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_EVENT);
}

/*
** This function is used to set the PARAM SET of EDMA3 for the Receive Channel
** of UART. EDMA3 Enable Transfer is also called within this API.
*/

static void UartReceiveData(unsigned int tccNum, unsigned int chNum,
                            volatile char *buffer)
{
    EDMA3CCPaRAMEntry paramSet;

    /* Fill the PaRAM Set with transfer specific information */
    paramSet.srcAddr = UART_RBR_THR_REG;
    paramSet.destAddr = (unsigned int) buffer;
    paramSet.aCnt = MAX_ACNT;
    paramSet.bCnt = RX_BUFFER_SIZE;
    paramSet.cCnt = MAX_CCNT;

    /* The src index should not be increment since it is a h/w register*/
    paramSet.srcBIdx = 0;
    /* The dest index should incremented for every byte */
    paramSet.destBIdx = 1;

    /* A sync Transfer Mode */
    paramSet.srcCIdx = 0;
    paramSet.destCIdx = 0;
    paramSet.linkAddr = (unsigned short)0xFFFFu;
    paramSet.bCntReload = 0;
    paramSet.opt = 0x00000000u;    
    paramSet.opt |= ((EDMA3CC_OPT_SAM) << EDMA3CC_OPT_SAM_SHIFT); 
    paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
    paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);

    /* Now write the PaRAM Set */
    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, &paramSet);

    /* Enable EDMA Transfer */
    EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_EVENT);
}

/* Function used to Initialize EDMA3 */
static void EDMA3Initialize(void)
{

	 /* Enabling the PSC for EDMA3CC_0.*/
	PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON,
				 PSC_MDCTL_NEXT_ENABLE);

	/* Enabling the PSC for EDMA3TC_0.*/
	PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON,
			 PSC_MDCTL_NEXT_ENABLE);

	/* Initialization of EDMA3 */
    EDMA3Init(SOC_EDMA30CC_0_REGS, EVT_QUEUE_NUM);
   
    /*
    ** Enable AINTC to handle interuppts. Also enable IRQ interuppt in 
    ** ARM processor.
    */
    SetupInt();

    /* Register EDMA3 Interrupts */
    ConfigureIntEDMA3();
}

/* Function used to Setup ARM Interuppt Controller */
static void SetupInt(void)
{
#ifdef _TMS320C6X
	// Initialize the DSP Interrupt controller
	IntDSPINTCInit();

	// Enable DSP interrupts globally
	IntGlobalEnable();
#else
    /*Initialize the ARM Interrupt Controller(AINTC). */
    IntAINTCInit();

    /* Enable IRQ in CPSR.*/     
    IntMasterIRQEnable();

    /* Enable the interrupts in GER of AINTC.*/
    IntGlobalEnable();

    /* Enable the interrupts in HIER of AINTC.*/
    IntIRQEnable();
#endif
}

/* EDMA3 Completion Handler */
static void edma3ComplHandler(unsigned int baseAdd, unsigned int regionNum)
{
    volatile unsigned int pendingIrqs;
    volatile unsigned int isIPR = 0;

    unsigned int indexl;
    unsigned int Cnt = 0;
    indexl = 1;
    
#ifdef _TMS320C6X
    IntEventClear(SYS_INT_EDMA3_0_CC0_INT1);
#else
    IntSystemStatusClear(SYS_INT_CCINT0);
#endif
    isIPR = HWREG(baseAdd + EDMA3CC_S_IPR(regionNum));
    if(isIPR)
    {
        while ((Cnt < EDMA3CC_COMPL_HANDLER_RETRY_COUNT)&& (indexl != 0u))
        {
            indexl = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_S_IPR(regionNum));
            while (pendingIrqs)
            {
                if((pendingIrqs & 1u) == TRUE)
                {
                    /**
                    * If the user has not given any callback function
                    * while requesting the TCC, its TCC specific bit
                    * in the IPR register will NOT be cleared.
                    */
                    /* here write to ICR to clear the corresponding IPR bits */
                    HWREG(baseAdd + EDMA3CC_S_ICR(regionNum)) = (1u << indexl);

                    (*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE);
                }
                ++indexl;
                pendingIrqs >>= 1u;
            }
            Cnt++;
        }
    }
}

static void Edma3ComplHandlerIsr(void)
{
#ifdef _TMS320C6X
	// Invoke Completion Handler ISR
	edma3ComplHandler(SOC_EDMA30CC_0_REGS, 1);
#else
    /* Invoke Completion Handler ISR */
    edma3ComplHandler(SOC_EDMA30CC_0_REGS, 0);
#endif
}

/* EDMA3 Error Handler */
static void edma3CCErrHandler(unsigned int baseAdd)
{
    volatile unsigned int pendingIrqs = 0;
    unsigned int regionNum = 0;
    unsigned int evtqueNum = 0;  
    unsigned int index = 1;
    unsigned int Cnt = 0;
    
#ifdef _TMS320C6X
    IntEventClear(SYS_INT_EDMA3_0_CC0_ERRINT);
#else
    IntSystemStatusClear(SYS_INT_CCERRINT);
#endif

    if((HWREG(baseAdd + EDMA3CC_EMR) != 0 ) || \
       (HWREG(baseAdd + EDMA3CC_QEMR) != 0) || \
       (HWREG(baseAdd + EDMA3CC_CCERR) != 0))
    {
        /* Loop for EDMA3CC_ERR_HANDLER_RETRY_COUNT number of time, breaks 
           when no pending interrupt is found */
        while ((Cnt < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (index != 0u))
        {
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_EMR);
            while (pendingIrqs)
            {
                /*Process all the pending interrupts*/
                if((pendingIrqs & 1u)==TRUE)
                {
                    /* Write to EMCR to clear the corresponding EMR bits.*/
                    HWREG(baseAdd + EDMA3CC_EMCR) = (1u<<index);
                    /*Clear any SER*/
                    HWREG(baseAdd + EDMA3CC_S_SECR(regionNum)) = (1u<<index);
                }
                ++index;
                pendingIrqs >>= 1u;
            }
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_QEMR);
            while (pendingIrqs)
            {
                /*Process all the pending interrupts*/
                if((pendingIrqs & 1u)==TRUE)
                {
                    /* Here write to QEMCR to clear the corresponding QEMR bits*/
                    HWREG(baseAdd + EDMA3CC_QEMCR) = (1u<<index);
                    /*Clear any QSER*/
                    HWREG(baseAdd + EDMA3CC_S_QSECR(0)) = (1u<<index);
                }
                ++index;
                pendingIrqs >>= 1u;
            }
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_CCERR);
    if (pendingIrqs != 0u)
    {
        /* Process all the pending CC error interrupts. */
        /* Queue threshold error for different event queues.*/
        for (evtqueNum = 0u; evtqueNum < EDMA3_0_NUM_EVTQUE; evtqueNum++)
        {
            if((pendingIrqs & (1u << evtqueNum)) != 0u)
            {
                /* Clear the error interrupt. */
                HWREG(baseAdd + EDMA3CC_CCERRCLR) = (1u << evtqueNum);
            }
         }

         /* Transfer completion code error. */
         if ((pendingIrqs & (1 << EDMA3CC_CCERR_TCCERR_SHIFT)) != 0u)
         {
             HWREG(baseAdd + EDMA3CC_CCERRCLR) = \
                  (0x01u << EDMA3CC_CCERR_TCCERR_SHIFT);
         }
         ++index;
    }
    Cnt++;
        }
    }
}

static void Edma3CCErrHandlerIsr()
{
    /* Invoke CC Error Handler ISR */
    edma3CCErrHandler(SOC_EDMA30CC_0_REGS);
}

/* Function to register EDMA3 Interuppts */
static void ConfigureIntEDMA3(void)
{
    /* Register Interrupts Here */

//Note: ARM is used
#ifdef _TMS320C6X
	IntRegister(C674X_MASK_INT4, Edma3ComplHandlerIsr);
	IntRegister(C674X_MASK_INT5, Edma3CCErrHandlerIsr);

	IntEventMap(C674X_MASK_INT4, SYS_INT_EDMA3_0_CC0_INT1);
	IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_0_CC0_ERRINT);

	IntEnable(C674X_MASK_INT4);
	IntEnable(C674X_MASK_INT5);
#else
    IntRegister(SYS_INT_CCINT0, Edma3ComplHandlerIsr);

	IntChannelSet(SYS_INT_CCINT0, 2);
	//Should be IntChannelSet(SYS_INT_CCINT0, 1); or IntChannelSet(SYS_INT_CCINT0, 4);?

    IntSystemEnable(SYS_INT_CCINT0);

    IntRegister(SYS_INT_CCERRINT, Edma3CCErrHandlerIsr);

	IntChannelSet(SYS_INT_CCERRINT, 2);
	//Should be IntChannelSet(SYS_INT_CCINT0, 1); or IntChannelSet(SYS_INT_CCINT0, 4);?

    IntSystemEnable(SYS_INT_CCERRINT);
#endif
}


/*
** This function is used as a callback from EDMA3 Completion Handler. 
** UART in DMA Mode is Disabled over here.
*/
static void callback(unsigned int tccNum, unsigned int status)
{    
	UARTDMADisable(SOC_UART_1_REGS, (UART_RX_TRIG_LEVEL_1 | UART_FIFO_MODE));	
    flag = 1;
}

/********************************* End of file ******************************/

 


Viewing all articles
Browse latest Browse all 17527

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>