Hi,
I'm using C6746 DSP and I'm running into a problem that I don't know how to solve it.
I programmed the DMA (ping pong mode) + McBSP to receive data in 128 channels, process it and then transmit it.
Everything is working really well, but I noticed after some tests that, after booting the DSP around 40/50 times, one time the DMA starts with the timeslots shifted (sometimes 8 timeslots, sometimes 2, it's random) and this is turning into a problem because of the randomness of it. Sometimes the shift occur after the second boot, sometimes after the 40th boot. We weren't able to determine a specific cause to this problem. We're afraid that this problem might occur during the field tests and become a headache for us.
When the boot is succesfull, the firmware works perfectly, the DMA does not crash. We're using the firmware here at our company for 4 weeks (we didn't restart our boards since then) and we didn't run at a single problem. So I believe that the McBSP + EDMA configuration is alright. The configuration order is:
McBSP parameters configuration (RX and TX still in reset)
EDMA parameters configuration
Interruption configuration
McBSP RX and TX out of reset.
The DSP receives from our FPGA the clock (8MHz), the Frame Sync (8kHz), all 128 channels and a 25MHz clock that we use instead of the oscillator. The FPGA is already booted and working when we begin to boot the DSP.
Any idea why does this happen? Am I doing something wrong? Is there any sync problem that I should be careful before starting the McBSP + DMA + interrupt?
Here's my main.c that configures the DMA and McBSP.
//Khomp Ind�stria e Com�rcio ltda. //October 2013 - April 2014 //Texas C6746 with ECU package //Leonardo Batista Trierveiler #include <stdio.h> #include <string.h> #include <cslr/cslr_syscfg0_C6748.h> #include <cslr/soc_C6748.h> #include <cslr/cslr_dspintc.h> #include <cslr/cslr_chip.h> #include <cslr/cslr_aintc.h> #include <cslr/cslr_mcbsp.h> #include <cslr/cslr_spi.h> #include <cslr/cslr_tmr.h> #include <cslr/cslr.h> #include <cslr/cslr_cache.h> #include <c6x.h> #define MAP_LOCAL_TO_GLOBAL_ADDR(addr) ((1<<28)|(DNUM<<24)|(((unsigned int)addr)&0x00ffffff)) #define FRAME_SIZE 80 #define C6746_INTC_REGS_BASE_ADDRESS 0x01800000 #define MCBSP0_RCV_INT_CPU 87 #define MCBSP0_XMT_INT_CPU 88 #define EDMA3_0_CC0_INT1_CPU 8 #define EDMA3_0_CC0_ERRINT_CPU 56 #define SPI1_INT_CPU 43 #define SPI1_RCV_INT_EDMA 18 #define SPI1_XMT_INT_EDMA 19 #define MCBSP0_RCV_INT_EDMA 2 #define MCBSP0_XMT_INT_EDMA 3 /////////////DMA CONFIGURATION/////////////// #define ACNT_RX 1 //Number of bytes #define BCNT_RX 128 //Number of frames - number of channels #define CCNT_RX 80 //Number of arrays - number of samples per channel #define BCNTRLD_RX BCNT_RX #define RX_BIDX_SRC 0 #define RX_BIDX_DST CCNT_RX #define RX_CIDX_SRC 0 #define RX_CIDX_DST (1 - ACNT_RX*(BCNT_RX-1)*CCNT_RX) #define ACNT_TX 1 //Number of bytes #define BCNT_TX 128 //Number of frames - number of channels #define CCNT_TX 80 //Number of arrays - number of samples per channel #define BCNTRLD_TX BCNT_TX #define TX_BIDX_SRC CCNT_TX #define TX_BIDX_DST 0 #define TX_CIDX_SRC (1 - ACNT_TX*(BCNT_TX-1)*CCNT_TX) #define TX_CIDX_DST 0 /////////////DMA CONFIGURATION/////////////// CSL_DspintcRegsOvly intcRegs = (CSL_DspintcRegsOvly)C6746_INTC_REGS_BASE_ADDRESS; void gpio_set_led(void); void delay (short i); void edma_config(void); int* getGlobalAddr(int* addr); extern void _intcVectorTable(void); void echo_cancel(void); volatile int cntr = 0x00000; //ECU buffers volatile char src_buff3[ACNT_RX*BCNT_RX*CCNT_RX]; volatile char src_buff4[ACNT_RX*BCNT_RX*CCNT_RX]; //ECU pointers char *RXECUBuff; char *RXECUBuff2; volatile char *ecurb; volatile unsigned char tgl = 0; volatile char led_on = 1; volatile int teste3 = 0; volatile short ecu_start = 0; //Interrupt Setting void set_intc (void) { ISTP = (unsigned int)_intcVectorTable; CSL_FINS(intcRegs->INTMUX1, DSPINTC_INTMUX1_INTSEL4,EDMA3_0_CC0_INT1_CPU); ICR = 0xFFF0; IER |= 0x12; _enable_interrupts(); } short jj; interrupt void _interrupt4(void) { ICR = 0x0000; IER &= 0xFFFFFF00; teste3++; //led counter if (tgl) ecurb = RXECUBuff2; else ecurb = RXECUBuff; tgl = !tgl; ecu_start = 1; // gpio set register if (cntr == 20) { led_on = !led_on; teste3 = 0; } if (led_on) { *((int *)0x01E26040) = 0x00000001; } else { *((int *)0x01E26044) = 0x00000001; } //ICR - Interrupt Clear Register - Global Region *((int *)0x01C01070) = 0xFFFFFFFF; *((int *)0x01C01040) = 0xFFFFFFFF; *((int *)0x01C00308) = 0xFFFFFFFF; ICR = 0xFFF0; IER |= 0x12; } int main() { volatile int j = 0, i = 0; RXECUBuff = (char *)getGlobalAddr((int *)src_buff3); RXECUBuff2 = (char *)getGlobalAddr((int *)src_buff4); //GPIO BANK 2, PIN 0 is bit 0 *((int*)0x01E26008) = 0x00000004; //BITEN *((int*)0x01E26038) = 0x00000000; //GPIO BANK 2, PIN 0 set as output *((int*)0x01E26040) = 0x00000000; *((int*)0x01E26044) = 0x00000001; *((int*)0x01E2604C) = 0x00000001; *((int*)0x01E26050) = 0x00000001; *((int*)0x01E26044) = 0x00000001; // McBSP0 RECEIVE INTERRUPT (CPU) = EVT 87 // McBSP0 TRANSMIT INTERRUPT (CPUT) = EVT 88 *((int*)0x01D10000) = 0x0; //DRR *((int*)0x01D10004) = 0x0; //DXR *((int*)0x01D10008) = 0x0; //SPCR *((int*)0x01D1000C) = 0x0; //RCR *((int*)0x01D10010) = 0x0; //XCR *((int*)0x01D10014) = 0x0; //SRGR *((int*)0x01D10018) = 0x0; //MCR *((int*)0x01D1001C) = 0x0; //RCERE0 *((int*)0x01D10020) = 0x0; //XCERE0 *((int*)0x01D10024) = 0x0; //PCR *((int*)0x01D10028) = 0x0; //RCERE1 *((int*)0x01D1002C) = 0x0; //XCERE1 *((int*)0x01D10030) = 0x0; //RCERE2 *((int*)0x01D10034) = 0x0; //XCERE2 *((int*)0x01D10038) = 0x0; //RCERE3 *((int*)0x01D1003C) = 0x0; //XCERE3 delay (4); //Serial Port Control Register (SPCR) //Bit 31->0 (Technical Reference Guide, page 1111/1112) //31-26 -> reserved = 0 23 -> FRST = 0 15 -> DLB = 0 7 -> DXENA = 0 // 22 -> GRST = 0 14-13 -> RJUST = 1h 6 -> reserved // 21-20 -> XINTM = 2h 5-4 -> RINTM = 2h // // 19 -> XSYNCERR = 0 12-11 -> CLKSTP = 0 3 -> RSYNCERR = 0 // 18 -> XEMPTY = 0 2 -> RFULL = 0 //25 -> FREE = 0 17 -> XRDY = 0 10-8 -> reserved 1 -> RRDY = 0 //24 -> SOFT = 0 16 -> XRST = 0 0 -> RRST = 0 // 0000 0000 0000 0000 0010 0000 0010 0000 //Hex = 0x00202020 *((int*)0x01D10008) = 0x00202020; // Receive Control Register (RCR) //Bit 31->0 (Technical Reference Guide, page 1113/1114) //31 -> RPHASE = 0 23-21 -> RWDLEN2 = 0h 15 -> reserved 7-5 -> RWDLEN1 = 0h //30-24 -> RFRLEN2 = 0 14-8 -> RFRLEN1 = 7Fh // // 20-19 -> RCOMPAND = 0 4 -> RWDREVRS = 0 // 3-0 -> reserved // 18 -> RFIG = 0 // 17-16 -> RDATDLY = 1h // //0000 0000 0000 0001 0111 1111 0000 0000 //Hex = 0x00013F00 *((int*)0x01D1000C) = 0x00017F00; // Transmit Control Register (XCR) //Bit 31->0 (Technical Reference Guide, page 1115-1116) //31 -> RPHASE = 0 23-21 -> RWDLEN2 = 0h 15 -> reserved 7-5 -> RWDLEN1 = 0h //30-24 -> RFRLEN2 = 0 14-8 -> RFRLEN1 = 7Fh // // 20-19 -> RCOMPAND = 0 4 -> RWDREVRS = 0 // 3-0 -> reserved // 18 -> RFIG = 0 // 17-16 -> RDATDLY = 1h // //0000 0000 0000 0001 0111 1111 0000 0000 //Hex = 0x00013F00 *((int*)0x01D10010) = 0x00017F00; // Multichannel Control Register (MCR) //Bit 31->0 (Technical Reference Guide, page 1118-1121) //31-26 -> reserved 15-10 -> reserved // 22-21 -> XPABLK = 0 6-5 -> RPABLK = 0 // // 20-18 -> XCBLK = 0 4-2 -> RCBLK = 0 // // //25 -> XMCME = 0 17-16 -> XMCM = 0 9 -> RMCME = 0 1 -> reserved //24-23 -> XPBBLK = 0 8-7 -> RPBBLK = 0 0 -> RMCM = 0 //0000 0000 0000 0000 0000 0000 0000 0000 //Hex = 0x00000000 *((int*)0x01D10018) = 0x00000000; // Pin Control Register (PCR) //Bit 31->0 (Technical Reference Guide, page 1126-1127) //31-14 -> reserved 7 -> SCLKME = 0 // 6-4 -> reserved // 13-12 -> reserved // // 11 -> FSXM = 0 3 -> FSXP = 0 // 10 -> FSRM = 0 2 -> FSPR = 0 // 9 -> CLKXM = 0 1 -> CLKXP = 0 // 8 -> CLKRM = 0 0 -> CLKRP = 0 //0000 0000 0000 0000 0000 0000 0000 0000 //Hex = 0x00000000 *((int*)0x01D10024) = 0x00000000; *((int*)0x01D10818) = 0x0; //RFIFOCTL *((int*)0x01D1081C) = 0x0; //RFIFOSTS *((int*)0x01D10810) = 0x0; //WFIFOCTL *((int*)0x01D10814) = 0x0; //WFIFOSTS // Read FIFO Control Register (RFIFOCTL) //Bit 31->0 (Technical Reference Guide, page 1131) //31-16 -> reserved 15-8 -> RNUMEVT = 0 7-0 -> RNUMDMA = 0 // // // // // // // 16 -> RENA = 0 //0000 0000 0000 0000 0000 0000 0000 0000 //Hex = 0x00010000 *((int*)0x01D10818) = 0x00000000; // Write FIFO Control Register (WFIFOCTL) //Bit 31->0 (Technical Reference Guide, page 1131) //31-16 -> reserved 15-8 -> WNUMEVT = 0 7-0 -> WNUMDMA = 0 // // // // // // // 16 -> WENA = 0 //0000 0000 0000 0000 0000 0000 0000 0000 //Hex = 0x00010000 *((int*)0x01D10810) = 0x00000000; *((int*)0x01D10008) = 0x00212020; //McBSP SPCR delay (50); *((int*)0x01D10008) = 0x00202020; //McBSP SPCR //EDMA configuration edma_config(); //Set interrupt set_intc(); (*(int *)0x01800020) = 0x00000100; //EVTFLAG 8 EDMA *((int*)0x01D10008) = 0x00212021; //McBSP SPCR //Enabling L2 cache (64kB) *((int *)0x01840000) = 0x00000002; //Enabling cache for 0xC000000 address *((int *)0x01848300) = 0x00000001; //MAR192 //Echo Canceller function echo_cancel(); return 0; } void edma_config (void) { // DMAQNUM0 - DMA Channel Queue Number Register *((int *)0x01C00240) = 0x00000000; // EESR - Event Enable Set Register *((int *)0x01C01030) = 0x0000000C; //DRAE1 *((int *)0x01C00348) = 0x0000000C; // paRAM settings: //RX Settings (Init. Address Channel 2 = 0x01C04040) // OPT - Channel Options Parameters //31/28 -> reserved 23 -> ITCCHEN = 1 7/4 -> reserved // 22 -> TCCHEN = 0 // 21 -> ITCINTEN = 0 // 20 -> TCINTEN = 1 //27/24 -> PRIVID = 0 19/18 -> reserved 11 -> TCCMODE = 0 3 -> STATIC = 0 // 10/8 -> FWID = 2h 2 -> SYNCDIM = 0 // 17/12 -> TCC = 2h 1 -> DAM = 0 // 0 -> SAM = 0 // //HEX = 0000 0000 1001 0000 0010 0010 0000 0000 *((int *)0x01C04040) = 0x00102000; // SRC - Channel Source Address Parameter *((int *)0x01C04044) = (unsigned int) 0x01D10000; //RBUF DRR // A_B_CNT - A Count/B Count Parameter //31/16 -> BCNT = 8 15/0 -> ACNT = 4 // 0000 0000 0000 1000 0000 0000 0000 0100 //Hex = 0x00080004 *((int *)0x01C04048) = ((BCNT_RX << 16) | ACNT_RX); // DST - Channel Destiny Address Parameter *((int *)0x01C0404C) = (unsigned int) RXECUBuff; // SRC_DST_BIDX - Source B Index/Destination B Index Parameter //31/16 -> DSTBIDX = 4 15/0 -> SRCBIDX = 0 // 0000 0000 0000 0100 0000 0000 0000 0000 //Hex = 0x00010000 *((int *)0x01C04050) = (unsigned short) RX_BIDX_SRC; *((int *)0x01C04050) |= (RX_BIDX_DST << 16); // LINK_BCNTRLD - Link Address/B Count Reload Parameter //31/16 -> BCNTRLD = 8 15/0 -> LINK = 0x4400 // 0000 0000 0000 1000 0100 0100 0000 0000 //Hex = 0x00020000 *((int *)0x01C04054) = 0x00004440; *((int *)0x01C04054) |= (BCNTRLD_RX << 16); // SRC_DST_CIDX - Source C Index/Destination C Index Parameter //31/16 -> DSTCIDX = 0 15/0 -> SRCCIDX // 0000 0000 0000 0000 0000 0000 0000 0000 //Hex = 0x00000000 *((int *)0x01C04058) = (unsigned short) RX_CIDX_SRC; *((int *)0x01C04058) |= (RX_CIDX_DST << 16); //CCNT - C Count Parameter //31/16 -> reserved 15/0 -> CCNT = 1 // 0000 0000 0000 0000 0000 0000 0000 0001 //Hex = 0x00000001 *((int *)0x01C0405C) = CCNT_RX; //Link RX paRAM (channel 32, address: 0x01C04400) - PING // OPT - Channel Options Parameters *((int *)0x01C04400) = 0x00102000; // SRC - Channel Source Address Parameter *((int *)0x01C04404) = (unsigned int) 0x01D10000; //RBUF DRR // A_B_CNT - A Count/B Count Parameter *((int *)0x01C04408) = ((BCNT_RX << 16) | ACNT_RX); // DST - Channel Destiny Address Parameter *((int *)0x01C0440C) = (unsigned int) RXECUBuff; // SRC_DST_BIDX - Source B Index/Destination B Index Parameter *((int *)0x01C04410) = (unsigned short) RX_BIDX_SRC; *((int *)0x01C04410) |= (RX_BIDX_DST << 16); // LINK_BCNTRLD - Link Address/B Count Reload Parameter *((int *)0x01C04414) = 0x00004440; *((int *)0x01C04414) |= BCNTRLD_RX << 16; // SRC_DST_CIDX - Source C Index/Destination C Index Parameter *((int *)0x01C04418) = (unsigned short) RX_CIDX_SRC; *((int *)0x01C04418) |= (RX_CIDX_DST << 16); //CCNT - C Count Parameter *((int *)0x01C0441C) = CCNT_RX; //Link RX paRAM (channel 34, address: 0x01C04440) - PONG // OPT - Channel Options Parameters *((int *)0x01C04440) = 0x00102000; // SRC - Channel Source Address Parameter *((int *)0x01C04444) = (unsigned int) 0x01D10000; //RBUF DRR // A_B_CNT - A Count/B Count Parameter *((int *)0x01C04448) = ((BCNT_RX << 16) | ACNT_RX); // DST - Channel Destiny Address Parameter *((int *)0x01C0444C) = (unsigned int) RXECUBuff2; // SRC_DST_BIDX - Source B Index/Destination B Index Parameter *((int *)0x01C04450) = (unsigned short) RX_BIDX_SRC; *((int *)0x01C04450) |= (RX_BIDX_DST << 16); // LINK_BCNTRLD - Link Address/B Count Reload Parameter *((int *)0x01C04454) = 0x00004400; *((int *)0x01C04454) |= BCNTRLD_RX << 16; // SRC_DST_CIDX - Source C Index/Destination C Index Parameter *((int *)0x01C04458) = (unsigned short) RX_CIDX_SRC; *((int *)0x01C04458) |= (RX_CIDX_DST << 16); //CCNT - C Count Parameter *((int *)0x01C0445C) = CCNT_RX; //TX Settings (Init. Address Channel 3 = 0x01C04060) // OPT - Channel Options Parameters //31/28 -> reserved 23 -> ITCCHEN = 0 7/4 -> reserved // 22 -> TCCHEN = 0 // 21 -> ITCINTEN = 0 // 20 -> TCINTEN = 1 //27/24 -> PRIVID = 0 19/18 -> reserved 11 -> TCCMODE = 0 3 -> STATIC = 0 // 10/8 -> FWID = 2h 2 -> SYNCDIM = 0 // 17/12 -> TCC = 3h 1 -> DAM = 0 // 0 -> SAM = 0 // //HEX = 0000 0000 0001 0000 0011 0010 0000 0000 *((int *)0x01C04060) = 0x00103000; // SRC - Channel Source Address Parameter *((int *)0x01C04064) = (unsigned int)RXECUBuff; // A_B_CNT - A Count/B Count Parameter //31/16 -> BCNT = 8 15/0 -> ACNT = 4 // 0000 0000 0000 1000 0000 0000 0000 0100 //Hex = 0x00080004 *((int *)0x01C04068) = ((BCNT_TX << 16) | ACNT_TX); // DST - Channel Destiny Address Parameter *((int *)0x01C0406C) = (unsigned int) 0x01D10004; //XBUF DXR // SRC_DST_BIDX - Source B Index/Destination B Index Parameter //31/16 -> DSTBIDX = 0 15/0 -> SRCBIDX = 4 // 0000 0000 0000 0000 0000 0000 0000 0100 //Hex = 0x00000004 *((int *)0x01C04070) = (unsigned short) TX_BIDX_SRC; *((int *)0x01C04070) |= (TX_BIDX_DST << 16); // LINK_BCNTRLD - Link Address/B Count Reload Parameter //31/16 -> BCNTRLD = 8 15/0 -> LINK = 4420 // 0000 0000 0000 1000 0100 0100 0010 0000 //Hex = 0x00084420 *((int *)0x01C04074) = 0x00004460; *((int *)0x01C04074) |= BCNTRLD_TX << 16; // SRC_DST_CIDX - Source C Index/Destination C Index Parameter //31/16 -> DSTCIDX = 0 15/0 -> SRCCIDX // 0000 0000 0000 0000 0000 0000 0000 0000 //Hex = 0x00000000 *((int *)0x01C04078) = (unsigned short) TX_CIDX_SRC; *((int *)0x01C04078) |= (TX_CIDX_DST << 16); //CCNT - C Count Parameter //31/16 -> reserved 15/0 -> CCNT = 1 // 0000 0000 0000 0000 0000 0000 0000 0001 //Hex = 0x00000001 *((int *)0x01C0407C) = CCNT_TX; //Link TX paRAM (channel 33, address: 0x01C04420) - PING *((int *)0x01C04420) = 0x00103000; // SRC - Channel Source Address Parameter *((int *)0x01C04424) = (unsigned int)RXECUBuff; // A_B_CNT - A Count/B Count Parameter *((int *)0x01C04428) = ((BCNT_TX << 16) | ACNT_TX); // DST - Channel Destiny Address Parameter *((int *)0x01C0442C) = (unsigned int)0x01D10004; //XBUF DXR // SRC_DST_BIDX - Source B Index/Destination B Index Parameter *((int *)0x01C04430) = (unsigned short) TX_BIDX_SRC; *((int *)0x01C04430) |= (TX_BIDX_DST << 16); // LINK_BCNTRLD - Link Address/B Count Reload Parameter *((int *)0x01C04434) = 0x00004460; *((int *)0x01C04434) |= BCNTRLD_TX << 16; // SRC_DST_CIDX - Source C Index/Destination C Index Parameter *((int *)0x01C04438) = (unsigned short) TX_CIDX_SRC; *((int *)0x01C04438) |= (TX_CIDX_DST << 16); //CCNT - C Count Parameter *((int *)0x01C0443C) = CCNT_TX; //Link TX paRAM (channel 35, address: 0x01C04460) - PONG *((int *)0x01C04460) = 0x00103000; // SRC - Channel Source Address Parameter *((int *)0x01C04464) = (unsigned int)RXECUBuff2; // A_B_CNT - A Count/B Count Parameter *((int *)0x01C04468) = ((BCNT_TX << 16) | ACNT_TX); // DST - Channel Destiny Address Parameter *((int *)0x01C0446C) = (unsigned int)0x01D10004; //XBUF DXR // SRC_DST_BIDX - Source B Index/Destination B Index Parameter *((int *)0x01C04470) = (unsigned short) TX_BIDX_SRC; *((int *)0x01C04470) |= (TX_BIDX_DST << 16); // LINK_BCNTRLD - Link Address/B Count Reload Parameter *((int *)0x01C04474) = 0x00004420; *((int *)0x01C04474) |= BCNTRLD_TX << 16; // SRC_DST_CIDX - Source C Index/Destination C Index Parameter *((int *)0x01C04478) = (unsigned short) TX_CIDX_SRC; *((int *)0x01C04478) |= (TX_CIDX_DST << 16); //CCNT - C Count Parameter *((int *)0x01C0447C) = CCNT_TX; // IESR - Interrupt Enable Set Register - Global Region *((int *) 0x01C01060) = 0x00000004; //ICR - Interrupt Clear Register - Global Region *((int *) 0x01C01070) = 0xFFFFFFFF; //SECR - Secondary Event Clear Register *((int *)0x01C01040) = 0xFFFFFFFF; //EMCR - Event Missed Clear Register *((int *)0x01C00308) = 0xFFFFFFFF; } void delay (short i) { volatile int j = 0; for (j = 0; j < i*0x1000; j++) j = j; } signed int* getGlobalAddr(signed int* addr) { if (((unsigned int)addr & (unsigned int)0xFF000000) != 0) { return (addr); /* The address is already a global address */ } return((signed int*)(MAP_LOCAL_TO_GLOBAL_ADDR(addr))); } //31 -> 23 -> 15 -> 7 -> //30 -> 22 -> 14 -> 6 -> //29 -> 21 -> 13 -> 5 -> //28 -> 20 -> 12 -> 4 -> //27 -> 19 -> 11 -> 3 -> //26 -> 18 -> 10 -> 2 -> //25 -> 17 -> 9 -> 1 -> //24 -> 16 -> 8 -> 0 -> // //Hex = 0x
Thank in advance.
Best Regards,
Leonardo Trierveiler.