I made a small test program to check the functionality of the EDMA data transfer when the MCBSP triggers a REVT event. I achieved to receive an interrupt when EDMA completes data transfer to the receive buffer. However, this only happens once, after I have received the first frame. The next coming frames do not generate any interrupts unless the DSP is restarted. So my question is why I am receiving ONLY the first interrupt and how can I fix it.
After modifying the code slightly, I have checked that the MCBSP still receives data, as can be seen in MCBSP_rrdy() and MCBSP_read(), but the data cannot be seen in the receive buffer, where the EDMA is expected to copy the data into, before generating the interrupt. So I guess the problem is somehow related to the fact that EDMA is not receiving MCBSP REVT events anymore after the first frame is completed
I attach the sample code below:
#include <csl.h> #include <csl_mcbsp.h> #include <csl_edma.h> #include <csl_dma.h> #include <csl_irq.h> #include <stdio.h> #define BUFFER_SIZE_T 1 static MCBSP_Handle hMcbsp1; /* handle for McBSP1 */ static EDMA_Handle hEdma15; /* handle for EDMA 15 */ static volatile int receive_done = FALSE; static char recv_msg[BUFFER_SIZE_T] = "T"; #pragma DATA_SECTION(recvbuf1,"recv_buf"); unsigned char recvbuf1[0x0400]; /* Include the vector table to call the IRQ ISRs hookup */ extern far void vectors(); /* Prototypes */ static void ConfigMcBSP(void); static void ConfigEDMA(void); static void ProcessReceiveChar(unsigned char *); static char VoteLogic(unsigned char); interrupt void c_int08(void); void main() { int waittime = 0; unsigned char* rec_buffer = &recvbuf1[0]; /* initialize the CSL library */ CSL_init(); /* enable NMI and GI */ IRQ_nmiEnable(); IRQ_globalEnable(); /* point to the IRQ vector table */ IRQ_setVecs(vectors); /* disable and clear the event interrupt */ IRQ_reset(IRQ_EVT_EDMAINT); /* clear Parameter RAM of EDMA */ EDMA_clearPram(0x00000000); hEdma15 = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); hMcbsp1 = MCBSP_open(MCBSP_DEV1, MCBSP_OPEN_RESET); /* Configure the EDMA channels */ ConfigEDMA(); IRQ_enable(IRQ_EVT_EDMAINT); /* enable EDMA channel interrupt to CPU */ EDMA_intEnable(EDMA_CHA_REVT1); /* Enable EDMA channels */ EDMA_enableChannel(hEdma15); /* Setup for McBSP */ ConfigMcBSP(); /* Start Sample Rate Generator: set /GRST = 1 */ MCBSP_enableSrgr(hMcbsp1); /* inserted wait time for McBSP to get ready */ for (waittime=0; waittime<0xF; waittime++); /* Wake up the McBSP as transmitter and receiver */ MCBSP_enableRcv(hMcbsp1); MCBSP_enableXmt(hMcbsp1); //printf("Enable Frame Sync Generator for McBSP...\n\n"); /* Enable Frame Sync Generator for McBSP 1: set /FRST = 1 */ MCBSP_enableFsync(hMcbsp1); printf("Waiting for completion...\n\n"); /* To flag an interrupt to the CPU when EDMA transfer/receive is done */ for (;;) { /* now wait until the value is received then read it */ while (!receive_done); receive_done = FALSE; /* process received data */ printf("Processing Receive string. . \n"); ProcessReceiveChar(rec_buffer++); printf("String received: %s", recv_msg); } IRQ_disable(IRQ_EVT_EDMAINT); EDMA_RSET(CIER, 0x0); MCBSP_close(hMcbsp1); /* close McBSP 1 */ EDMA_close(hEdma15); /* close EDMA 15 */ for (;;); } void ConfigEDMA(void) { EDMA_configArgs(hEdma15, EDMA_OPT_RMK( EDMA_OPT_PRI_HIGH, /* 1 */ EDMA_OPT_ESIZE_8BIT, /* 01 */ EDMA_OPT_2DS_NO, /* 0 */ EDMA_OPT_SUM_NONE, /* 00 */ EDMA_OPT_2DD_NO, /* 0 */ EDMA_OPT_DUM_INC, /* 01 */ EDMA_OPT_TCINT_YES, /* 1 */ EDMA_OPT_TCC_OF(15), /* 15 */ EDMA_OPT_LINK_NO, /* 0 */ EDMA_OPT_FS_NO /* 0 */ ), /* SRC Setup */ EDMA_SRC_RMK(MCBSP_getRcvAddr(hMcbsp1)), /* CNT Setup */ EDMA_CNT_RMK(0, (BUFFER_SIZE_T * 10)), /* DST Setup */ EDMA_DST_RMK((Uint32) recvbuf1), /*recvbuf address*/ /* IDX Setup */ EDMA_IDX_RMK(0,0), /* RLD Setup */ EDMA_RLD_RMK(0,0) ); } /* End of ConfigEDMA() */ void ConfigMcBSP(void) { MCBSP_Config mcbspCfg1 = { MCBSP_SPCR_RMK( MCBSP_SPCR_FREE_YES, /* 1 */ MCBSP_SPCR_SOFT_DEFAULT, /* 0 */ MCBSP_SPCR_FRST_DEFAULT, /* 0 */ MCBSP_SPCR_GRST_DEFAULT, /* 0 */ MCBSP_SPCR_XINTM_XRDY, /* 00 */ MCBSP_SPCR_XSYNCERR_DEFAULT, /* 0 */ MCBSP_SPCR_XRST_DEFAULT, /* 0 */ MCBSP_SPCR_DLB_OFF, /* 0 */ MCBSP_SPCR_RJUST_RZF, /* 00 */ MCBSP_SPCR_CLKSTP_DISABLE, /* 0 */ MCBSP_SPCR_DXENA_OFF, /* 0 */ MCBSP_SPCR_RINTM_RRDY, /* 00 */ MCBSP_SPCR_RSYNCERR_DEFAULT, /* 0 */ MCBSP_SPCR_RRST_DEFAULT /* 0 */ ), MCBSP_RCR_RMK( MCBSP_RCR_RPHASE_SINGLE, /* 1 */ MCBSP_RCR_RFRLEN2_DEFAULT, /* 00010 */ MCBSP_RCR_RWDLEN2_DEFAULT, /* 000 */ MCBSP_RCR_RCOMPAND_MSB, /* 00 */ MCBSP_RCR_RFIG_YES, /* 1 */ MCBSP_RCR_RDATDLY_1BIT, /* 01 */ MCBSP_RCR_RFRLEN1_OF(9), /* 01000 */ MCBSP_RCR_RWDLEN1_8BIT, /* 010 */ MCBSP_RCR_RWDREVRS_DISABLE /* 0 */ ), MCBSP_XCR_RMK( MCBSP_XCR_XPHASE_SINGLE, /* 1 */ MCBSP_XCR_XFRLEN2_DEFAULT, /* 00010 */ MCBSP_XCR_XWDLEN2_DEFAULT, /* 000 */ MCBSP_XCR_XCOMPAND_MSB, /* 00 */ MCBSP_XCR_XFIG_YES, /* 1 */ MCBSP_XCR_XDATDLY_0BIT, /* 00 */ MCBSP_XCR_XFRLEN1_OF(9), /* 01000 */ // Start + end + 8 bits (words) MCBSP_XCR_XWDLEN1_8BIT, /* 010 */ MCBSP_XCR_XWDREVRS_DISABLE /* 0 */ ), /* SRGR Setup */ MCBSP_SRGR_RMK( MCBSP_SRGR_GSYNC_FREE, /* 0 */ MCBSP_SRGR_CLKSP_RISING, /* 0 */ MCBSP_SRGR_CLKSM_INTERNAL, /* 1 */ MCBSP_SRGR_FSGM_DXR2XSR, /* 0 */ MCBSP_SRGR_FPER_DEFAULT, /* 0 */ MCBSP_SRGR_FWID_DEFAULT, /* 0 */ MCBSP_SRGR_CLKGDV_OF(121) /* CLKGDV */ ), /* MCR Setup */ MCBSP_MCR_DEFAULT, /* default values */ MCBSP_RCER_DEFAULT, /* default values */ MCBSP_XCER_DEFAULT, /* default values */ /* PCR Setup */ MCBSP_PCR_RMK( MCBSP_PCR_XIOEN_SP, /* 0 */ MCBSP_PCR_RIOEN_SP, /* 0 */ MCBSP_PCR_FSXM_INTERNAL, /* 1 */ MCBSP_PCR_FSRM_EXTERNAL, /* 0 */ MCBSP_PCR_CLKXM_OUTPUT, /* 1 */ MCBSP_PCR_CLKRM_OUTPUT, /* 1 */ MCBSP_PCR_CLKSSTAT_0, /* 0 */ MCBSP_PCR_DXSTAT_0, /* 0 */ MCBSP_PCR_FSXP_ACTIVELOW, /* 1 */ MCBSP_PCR_FSRP_ACTIVELOW, /* 1 */ MCBSP_PCR_CLKXP_RISING, /* 0 */ MCBSP_PCR_CLKRP_FALLING /* 0 */ ) }; MCBSP_config(hMcbsp1, &mcbspCfg1); } /* end of Config_McBSP(void) */ void ProcessReceiveChar(unsigned char * recvbuffer) { int i; unsigned char recv_char = 0; short cnt = -1; short recv_val; unsigned char raw_data; unsigned char *recvbufptr; /*receive buffer pointer*/ /* Point to the receive buffer */ recvbufptr = recvbuffer; /* Process all data in the Receive buffer */ for (i = 0; i < BUFFER_SIZE_T; i++) { printf("PROCESSING CHAR %d: ", i); recv_char = 0; /* Process each UART frame */ for (cnt = -1; cnt < 9; cnt++) { printf("%X, ", *recvbufptr); if(cnt == -1 || cnt == 8) { /* Ignore Start and Stop bits */ *recvbufptr++; } else { /* Get 8-bit data from receive buffer */ raw_data = *recvbufptr; recvbufptr++; /* get the value of the majority of the bits */ recv_val = VoteLogic(raw_data); /* put received bit into proper place */ recv_char += recv_val << cnt; } } /* end for cnt */ /* A full BYTE is decoded. Put in result: recv_msg[i] */ recv_msg[i] = recv_char; } /* end for i */ printf("\n"); } /* end ProcessReceiveData() function */ char VoteLogic(unsigned char value) { short returnvalue; switch ((value >> 2) & 0x0F) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 8: case 9: case 10: returnvalue = 0; break; case 7: case 11: case 12: case 13: case 14: case 15: returnvalue = 1 ; break; } /* end switch */ return (returnvalue); } /* end VoteLogic() funciton */ interrupt void c_int08(void) { volatile Uint8 *ledReg; volatile Uint8 ledStatus; if (EDMA_intTest(15)) { EDMA_intClear(15); receive_done = TRUE; printf("Receive Completed\n\n"); ledReg = (volatile Uint8 *) 0x90080000; ledStatus = *(ledReg); ledStatus &= 0xF0; // turn off all LEDs ledStatus |= (0x0F); // turn on LEDs *ledReg = ledStatus; } }