Other Parts Discussed in Thread: SYSBIOS, OMAP-L138, MATHLIB, BIOSSW-C6748
Hi,
I want to port Uart EDMA Starterware project to SYSBIOS 6 on OMAP L138 LCDK (CCS 5.4). The code in Startware of this example first sends out a string:
volatile char enter[] = "\r\nPlease Enter 20 bytes from keyboard\r\n";
After I modify interrupt initialization:
/* Function to register EDMA3 Interrupts */
static void ConfigureIntEDMA3(void)
{
/* Register Interrupts Here */#ifdef _TMS320C6X
// IntRegister(C674X_MASK_INT4, Edma3ComplHandlerIsr);
IntRegister(C674X_MASK_INT7, Edma3ComplHandlerIsr);
IntRegister(C674X_MASK_INT5, Edma3CCErrHandlerIsr);// IntEventMap(C674X_MASK_INT4, SYS_INT_EDMA3_0_CC0_INT1);
IntEventMap(C674X_MASK_INT7, SYS_INT_EDMA3_0_CC0_INT1);
IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_0_CC0_ERRINT);// IntEnable(C674X_MASK_INT4);
IntEnable(C674X_MASK_INT7);
IntEnable(C674X_MASK_INT5);...............
/* 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 interrupts. Also enable IRQ interrupt in
** ARM processor.
*/
SetupInt();/* Register EDMA3 Interrupts */
ConfigureIntEDMA3();
}/* Function used to Setup ARM Interrupt 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
}
The console receives some erroneaous words, although I can tell several words such as ease key (which are obvious from the original string).
The original Starterware project EDMA3 use 2 interrupts (INT4, INT5). Due to confilicts with SYSBIOS, I change INT4 to INT7 as:
// IntRegister(C674X_MASK_INT4, Edma3ComplHandlerIsr);
IntRegister(C674X_MASK_INT7, Edma3ComplHandlerIsr);
IntRegister(C674X_MASK_INT5, Edma3CCErrHandlerIsr);
What is wrong with my code? Thanks
/*
* ======== static.c ========
* The static example focuses on SYS/BIOS configuration. It shows how to
* - Use and configure various modules.
* - Create static Instances.
* - Modify Program level configuration parameters.
*/
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Swi.h>
#include <ti/sysbios/knl/Clock.h>
#include <xdc/cfg/global.h>
#include "hw_psc_OMAPL138.h"
#include "soc_OMAPL138.h"
#include "interrupt.h"
#include "lcdkOMAPL138.h"
#include "hw_types.h"
#include "edma.h"
#include "string.h"
#include "edma_event.h"
#include "uartStdio.h"
#include "uart.h"
#include "psc.h"
/****************************************************************************/
/* INTERNAL MACRO DEFINITIONS */
/****************************************************************************/
#define UART_RBR_THR_REG ((0x01D0D000u) + (0u))
#define MAX_ACNT 1
#define MAX_CCNT 1
#define RX_BUFFER_SIZE 20
/* EDMA3 Event queue number. */
#define EVT_QUEUE_NUM 0
/****************************************************************************/
/* LOCAL FUNCTION PROTOTYPES */
/****************************************************************************/
static void ConfigureIntUART(void);
static void SetupInt(void);
/****************************************************************************/
/* 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);
void Edma3ComplHandlerIsr(void);
//static void Edma3CCErrHandlerIsr(void);
void Edma3CCErrHandlerIsr(void);
static void EDMA3Initialize(void);
/****************************************************************************/
/* GLOBAL VARIABLES */
/****************************************************************************/
volatile unsigned int flag = 0;
//static void UARTIsr(void);
void uart2_ISR(void);
/****************************************************************************/
/* GLOBAL VARIABLES */
/****************************************************************************/
char txArray[] = "StarterWare UART echo application\n\r";
Void timerFunc(UArg arg);
/****************************************************************************/
/* LOCAL FUNCTION DEFINITIONS */
/****************************************************************************/
Bool finishFlag = FALSE;
/*
* ======== main ========
*/
Void main()
{
volatile char enter[] = "\r\nPlease Enter 20 bytes from keyboard\r\n";
volatile char buffer[RX_BUFFER_SIZE];
unsigned int buffLength = 0;
/* Initialize EDMA3 Controller */
EDMA3Initialize();
/* Initialize UART */
UARTStdioInit();
/* Request DMA Channel and TCC for UART Transmit*/
EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
EDMA3_CHA_UART2_TX, EDMA3_CHA_UART2_TX,
EVT_QUEUE_NUM);
/* Registering Callback Function for TX*/
cb_Fxn[EDMA3_CHA_UART2_TX] = &callback;
/* Request DMA Channel and TCC for UART Receive */
EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
EDMA3_CHA_UART2_RX, EDMA3_CHA_UART2_RX,
EVT_QUEUE_NUM);
/* Registering Callback Function for RX*/
cb_Fxn[EDMA3_CHA_UART2_RX] = &callback;
/* Used for bCnt */
buffLength = strlen((const char *) enter);
/* Transmit Data for Enter Message */
UartTransmitData(EDMA3_CHA_UART2_TX, EDMA3_CHA_UART2_TX,
enter, buffLength);
/* Enabling UART in DMA Mode*/
UARTDMAEnable(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1 | \
UART_DMAMODE | \
UART_FIFO_MODE );
Swi_post(swi0);
Swi_post(swi1);
Clock_start(clk1);
Hwi_enable();
Hwi_enableInterrupt(6);
BIOS_start();
}
/*
** 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 interrupts. Also enable IRQ interrupt in
** ARM processor.
*/
SetupInt();
/* Register EDMA3 Interrupts */
ConfigureIntEDMA3();
}
/* Function used to Setup ARM Interrupt 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)
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()
void Edma3CCErrHandlerIsr()
{
/* Invoke CC Error Handler ISR */
edma3CCErrHandler(SOC_EDMA30CC_0_REGS);
}
/* Function to register EDMA3 Interrupts */
static void ConfigureIntEDMA3(void)
{
/* Register Interrupts Here */
#ifdef _TMS320C6X
// IntRegister(C674X_MASK_INT4, Edma3ComplHandlerIsr);
IntRegister(C674X_MASK_INT7, Edma3ComplHandlerIsr);
IntRegister(C674X_MASK_INT5, Edma3CCErrHandlerIsr);
// IntEventMap(C674X_MASK_INT4, SYS_INT_EDMA3_0_CC0_INT1);
IntEventMap(C674X_MASK_INT7, SYS_INT_EDMA3_0_CC0_INT1);
IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_0_CC0_ERRINT);
// IntEnable(C674X_MASK_INT4);
IntEnable(C674X_MASK_INT7);
IntEnable(C674X_MASK_INT5);
#else
IntRegister(SYS_INT_CCINT0, Edma3ComplHandlerIsr);
IntChannelSet(SYS_INT_CCINT0, 2);
IntSystemEnable(SYS_INT_CCINT0);
IntRegister(SYS_INT_CCERRINT, Edma3CCErrHandlerIsr);
IntChannelSet(SYS_INT_CCERRINT, 2);
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_2_REGS, (UART_RX_TRIG_LEVEL_1 | UART_FIFO_MODE));
flag = 1;
}
/********************************* End of file ******************************/
/*
* ======== idl0Fxn ========
*/
Void idl0Fxn()
{
if (finishFlag) {
System_printf("Calling BIOS_exit from idl0Fxn\n");
// BIOS_exit(0);
}
while(1);
}
/*
* ======== swi0Fxn ========
*/
Void swi0Fxn(UArg arg0, UArg arg1)
{
System_printf("Running swi0Fxn\n");
// while(1);
}
/*
* ======== swi1Fxn ========
*/
Void swi1Fxn(UArg arg0, UArg arg1)
{
System_printf("Running swi1Fxn\n");
}
/*
* ======== clk0Fxn ========
*/
Void clk0Fxn(UArg arg0)
{
System_printf("Running clk0Fxn\n");
}
/*
* ======== clk1Fxn ========
*/
Void clk1Fxn(UArg arg0)
{
System_printf("Running clk1Fxn\n");
finishFlag = TRUE;
}
/*
* ======== timer0Fxn ========
*/
Void timer0Fxn()
{
System_printf("Running timer0Fxn\n");
}
/*
* ======== task0Fxn ========
*/
Void task0Fxn(UArg arg0, UArg arg1)
{
System_printf("Running task0Fxn\n");
}
/*
* ======== task1Fxn ========
*/
Void task1Fxn(UArg arg0, UArg arg1)
{
System_printf("Running task1Fxn\n");
}
/*
* ======== timerFunc ========
* This function runs every PERIOD ms in the context of a Hwi thread.
*/
Void timerFunc(UArg arg)
{
static UInt tickCount = 0;
/* change load values every 5 seconds * /
if (++tickCount >= (0.5 * NUMPERSEC)) {
tickCount = 0;
step();
}
/ * Make Swi load thread ready to run * /
Swi_post(swi);
/ * Make Task load thread ready to run * /
Semaphore_post(sem);
/ * Do Hwi thread load now * /
hwiLoad();*/
}