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, ¶mSet);
/* 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, ¶mSet);
/* 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, ¶mSet); /* 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, ¶mSet); /* 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 ******************************/