#include <csl_gpio.h>
#include <csl_edma3.h>
#include <csl_edma3Aux.h>
#include <csl_intc.h>
#include <csl_intcAux.h>
#include <stdio.h>
#include <string.h>
#include <cslr_dev.h>
#include <dsk6455.h>
#include <dsk6455_led.h>
volatile Uint8 intrCnt=0;
CSL_Edma3Handle hEdma;
void HandleEDMA_INT(void *arg)
{
CSL_Edma3CmdIntr regIntr;
intrCnt++;
regIntr.region = CSL_EDMA3_REGION_GLOBAL;
regIntr.intr = 0x00000000;
regIntr.intrh = 0xffffffff;
CSL_edma3HwControl(hEdma, CSL_EDMA3_CMD_INTRPEND_CLEAR, ®Intr);
}
void main(void)
{
Bool gpioEn;
CSL_Status status;
CSL_GpioObj gpioObj;
CSL_GpioHandle hGpio;
CSL_GpioConfig gpioCfg = CSL_GPIO_CONFIG_DEFAULTS;
CSL_GpioPinConfig pinCfg;
CSL_Edma3Obj edmaObj;
CSL_Edma3ChannelObj edmaChObj;
CSL_Edma3ChannelHandle hEdmaCh;
CSL_Edma3ChannelAttr edmaChAtt;
CSL_Edma3ParamSetup edmaParamSetup;
CSL_Edma3ParamHandle hParamSetup;
CSL_Edma3HwSetup edmaHwSetup;
CSL_Edma3HwDmaChannelSetup edmaDmaChSetup;
CSL_Edma3CmdDrae regionAccess;
CSL_Edma3CmdIntr regionIntr;
CSL_IntcObj edmaIntcObj;
CSL_IntcHandle hEdmaIntc;
CSL_IntcContext intcContext;
CSL_IntcEventHandlerRecord eventRecord[1];
CSL_IntcEventHandlerRecord edmaIsr;
CSL_IntcParam vectId;
CSL_IntcGlobalEnableState state;
volatile long int mem;
long int mem1;
mem = 0;
mem1 = 0;
DSK6455_LED_init();
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERLOCK, DEV_PERLOCK_LOCKVAL, UNLOCK);
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG0, DEV_PERCFG0_GPIOCTL, ENABLE);
do{
gpioEn = (Bool) CSL_FEXT(((CSL_DevRegs*)CSL_DEV_REGS)->PERSTAT0, DEV_PERSTAT0_GPIOSTAT);
}while(gpioEn != TRUE);
status = CSL_edma3Init(NULL);
if(status != CSL_SOK)
{
printf("Errore nell'inizializzazione della libreria API per il modulo EDMA\n");
}
intcContext.eventhandlerRecord = eventRecord;
intcContext.numEvtEntries = 1;
status = CSL_intcInit(&intcContext);
if(status != CSL_SOK)
{
printf("Errore nell'inizializzazione della libreria API per il controller degli interrupt\n");
}
status = CSL_intcGlobalNmiEnable();
if(status != CSL_SOK)
{
printf("Errore nell'abilitazione globale degli interrupt non mascherabili\n");
}
status = CSL_intcGlobalEnable(&state);
if(status != CSL_SOK)
{
printf("Errore nell'abilitazione globale degli interrupt\n");
}
vectId = CSL_INTC_VECTID_4;
hEdmaIntc = CSL_intcOpen(&edmaIntcObj, CSL_INTC_EVENTID_EDMA3CC_INT0, &vectId, &status);
if((hEdmaIntc == NULL) || (status != CSL_SOK))
{
printf("Errore nell'associazione dell'evento all'interrupt\n");
}
hEdma = CSL_edma3Open(&edmaObj, CSL_EDMA3, NULL, &status);
if((status != CSL_SOK) || (hEdma == NULL))
{
printf("Errore nell'istanziazione del modulo Edma\n");
}
edmaDmaChSetup.paramNum = 0;
edmaDmaChSetup.que = CSL_EDMA3_QUE_0;
edmaHwSetup.dmaChaSetup = &edmaDmaChSetup;
edmaHwSetup.qdmaChaSetup = NULL;
status = CSL_edma3HwSetup(hEdma, &edmaHwSetup);
if(status != CSL_SOK)
{
printf("Errore nella selezione della coda e del PaRam set per il modulo EDMA\n");
}
regionAccess.region = CSL_EDMA3_REGION_0;
regionAccess.drae = 0xffffffff;
regionAccess.draeh = 0xffffffff;
status = CSL_edma3HwControl(hEdma, CSL_EDMA3_CMD_DMAREGION_ENABLE, ®ionAccess);
if(status != CSL_SOK)
{
printf("Errore nell'abilitazione della regione 0 per il modulo EDMA\n");
}
*((volatile Uint32 *)0x02A01008) = 0xffffffff; // ECR
*((volatile Uint32 *)0x02A0100C) = 0xffffffff; // ECRH
edmaChAtt.chaNum = CSL_EDMA3_CHA_GPINT13;
edmaChAtt.regionNum = CSL_EDMA3_REGION_0;
hEdmaCh = CSL_edma3ChannelOpen(&edmaChObj, CSL_EDMA3, &edmaChAtt, &status);
if((status != CSL_SOK) || (hEdmaCh == NULL))
{
printf("Errore nell'istanziazione del canale Edma per l'evento GPINT13\n");
}
hParamSetup = CSL_edma3GetParamHandle(hEdmaCh, 0, &status);
if((status != CSL_SOK) || (hEdmaCh == NULL))
{
printf("Errore nell'acquisizione del riferimento al PaRam set per il canale Edma\n");
}
edmaParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
CSL_EDMA3_TCCH_DIS, \
CSL_EDMA3_ITCINT_DIS, \
CSL_EDMA3_TCINT_EN,\
61,CSL_EDMA3_TCC_NORMAL,\
CSL_EDMA3_FIFOWIDTH_NONE, \
CSL_EDMA3_STATIC_DIS, \
CSL_EDMA3_SYNC_A, \
CSL_EDMA3_ADDRMODE_INCR, \
CSL_EDMA3_ADDRMODE_INCR);
edmaParamSetup.srcAddr = 0x02b00020;
edmaParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(4, 1);
edmaParamSetup.dstAddr = (Uint32)&mem;
edmaParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0, 0);
edmaParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 0);
edmaParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
edmaParamSetup.cCnt = 1;
status = CSL_edma3ParamSetup(hParamSetup, &edmaParamSetup);
if(status != CSL_SOK)
{
printf("Errore nell'impostazione del PaRam set\n");
}
status = CSL_edma3HwChannelSetupQue(hEdmaCh, CSL_EDMA3_QUE_0);
if(status != CSL_SOK)
{
printf("Errore nell'associazione della coda al canale\n");
}
edmaIsr.arg = hEdmaIntc;
edmaIsr.handler = (CSL_IntcEventHandler)&HandleEDMA_INT;
status = CSL_intcPlugEventHandler(hEdmaIntc, &edmaIsr);
if(status != CSL_SOK)
{
printf("Errore nell'associazione dell'evento al corrispondente handler\n");
}
status = CSL_intcHwControl(hEdmaIntc, CSL_INTC_CMD_EVTENABLE, NULL);
if(status != CSL_SOK)
{
printf("Errore nell'abilitazione dell'evento\n");
}
regionIntr.region = CSL_EDMA3_REGION_0;
regionIntr.intr = 0x00000000;
regionIntr.intrh = 0xffffffff;
status = CSL_edma3HwControl(hEdma, CSL_EDMA3_CMD_INTR_ENABLE, ®ionIntr);
if(status != CSL_SOK)
{
printf("Errore nell'abilitazione dell'interrupt interno al DMA\n");
}
status = CSL_gpioInit(NULL);
if(status != CSL_SOK)
{
printf("Errore nell'inizializzazione della libreria API per il GPIO\n");
}
hGpio = CSL_gpioOpen(&gpioObj, CSL_GPIO, NULL, &status);
if((status != CSL_SOK) || (hGpio == NULL))
{
printf("Errore nell'istanziazione della periferica GPIO\n");
}
status = CSL_gpioHwSetupRaw(hGpio, &gpioCfg);
status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_BANK_INT_ENABLE, NULL);
if(status != CSL_SOK)
{
printf("Errore nell'abilitazione degli interrupt per il GPIO\n");
}
*((volatile Uint32*) 0x02b00024) = 0x00002000;
pinCfg.pinNum = (CSL_GpioPinNum)13;
pinCfg.direction = CSL_GPIO_DIR_OUTPUT;
pinCfg.trigger = CSL_GPIO_TRIG_RISING_EDGE;
status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_CONFIG_BIT, &pinCfg);
if(status != CSL_SOK)
{
printf("Errore nella configurazione del pin numero 13\n");
}
status = CSL_edma3HwChannelControl(hEdmaCh, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);
if(status != CSL_SOK)
{
printf("Errore nell'abilitazione del canale Edma\n");
}
status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_SET_BIT, &(pinCfg.pinNum));
if(status != CSL_SOK)
{
printf("Errore nella transizione 0->1 del pin numero 13\n");
}
while(1)
{
if(intrCnt == 1)
{
DSK6455_LED_on(0);
DSK6455_waitusec(3000000);
DSK6455_LED_off(0);
break;
}
}
mem1 = *((long int *)0x02b00020);
status = CSL_gpioClose(hGpio);
status = CSL_intcClose(hEdmaIntc);
}
Hello everybody,
I was trying to do the following: use a GPIO pin to trigger the EDMA in order to trasfer the content of GPIO IN_DATA register to a variable located somewhere into memory and originally set to 0. I wrote the program code so that when the EDMA transfer is over, the completion interrupt starts the execution of a function that switches on a led for a few seconds; this way I'm sure the EDMA transfer is triggered and ends with success. But the variable that should be set with the content of the GPIO IN_DATA register contains its original value instead. I tried to explicitly assign the IN_DATA content to another variable, and this worked, but I would like to get the same result using the EDMA.
This is part of the code I wrote:
volatile long int mem; //destination of the EDMA transfer
edmaParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \ //PaRam setting; GPIO pin 13 used to trigger the transfer
CSL_EDMA3_TCCH_DIS, \
CSL_EDMA3_ITCINT_DIS, \
CSL_EDMA3_TCINT_EN,\
61,CSL_EDMA3_TCC_NORMAL,\
CSL_EDMA3_FIFOWIDTH_NONE, \
CSL_EDMA3_STATIC_DIS, \
CSL_EDMA3_SYNC_A, \
CSL_EDMA3_ADDRMODE_INCR, \
CSL_EDMA3_ADDRMODE_INCR);
edmaParamSetup.srcAddr = 0x02b00020; //address of the IN_DATA register
edmaParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(4, 1);
edmaParamSetup.dstAddr = (Uint32)&mem;
edmaParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0, 0);
edmaParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 0);
edmaParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
edmaParamSetup.cCnt = 1;
*((volatile Uint32*) 0x02b00024) = 0x00002000; //set the GPIO pin 13 to trigger at a rising edge
pinCfg.pinNum = (CSL_GpioPinNum)13;
pinCfg.direction = CSL_GPIO_DIR_OUTPUT;
pinCfg.trigger = CSL_GPIO_TRIG_RISING_EDGE;
status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_CONFIG_BIT, &pinCfg);
status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_SET_BIT, &(pinCfg.pinNum)); //manually trigger the EDMA
The full code is available in the file attached to this post.
Anyone could suggest a solution to this problem. Is EDMA failing the access to the register (still performing the transfer)? Are GPIO registers not accessible by EDMA ? Or maybe the destination variable is somehow protected from EDMA write operations?
Regards,
Francesco Annese