EDMA_Handle hEdmaReloadRcvPing; EDMA_Handle hEdmaReloadRcvPong; MCBSP_Handle hMcbsp1; // McBSP1 (codec data) handle Int16 gXmtChan; // TCC codes (see initEDMA()) Int16 gRcvChan; /* * EDMA Config data structure */ /* Transmit side EDMA configuration */ EDMA_Config gEdmaConfigXmt = { EDMA_FMKS(OPT, PRI, HIGH) | // Priority EDMA_FMKS(OPT, ESIZE, 16BIT) | // Element size EDMA_FMKS(OPT, 2DS, NO) | // 2 dimensional source? EDMA_FMKS(OPT, SUM, INC) | // Src update mode EDMA_FMKS(OPT, 2DD, NO) | // 2 dimensional dest EDMA_FMKS(OPT, DUM, NONE) | // Dest update mode EDMA_FMKS(OPT, TCINT, YES) | // Cause EDMA interrupt? EDMA_FMKS(OPT, TCC, OF(0)) | // Transfer complete code EDMA_FMKS(OPT, LINK, YES) | // Enable link parameters? EDMA_FMKS(OPT, FS, NO), // Use frame sync? (Uint32)&gBufferXmtPing, // Src address EDMA_FMK (CNT, FRMCNT, NULL) | // Frame count EDMA_FMK (CNT, ELECNT, BUFFSIZE), // Element count
MCBSP_FMKS(PCR, FSXM, EXTERNAL) | // Framesync- Signal für Sender kommt von extern (Slave) MCBSP_FMKS(PCR, FSRM, EXTERNAL) | // Framesync- Signal für Empfänger kommt von extern (Slave) MCBSP_FMKS(PCR, CLKXM, INPUT) | // Takt für Sender kommt von extern (Slave) MCBSP_FMKS(PCR, CLKRM, INPUT) | // Takt für Empfänger kommt von extern (Slave) MCBSP_FMKS(PCR, CLKSSTAT, DEFAULT) | // unrelevant da PINS keine GPIOs MCBSP_FMKS(PCR, DXSTAT, DEFAULT) | // unrelevant da PINS keine GPIOs MCBSP_FMKS(PCR, FSXP, ACTIVEHIGH) | // Framesync senderseitig ist "activehigh" MCBSP_FMKS(PCR, FSRP, ACTIVEHIGH) | // Framesync empfängerseitig ist "activehigh" MCBSP_FMKS(PCR, CLKXP, FALLING) | // Datum wird bei fallender Flanke gesendet MCBSP_FMKS(PCR, CLKRP, RISING) // Datum wird bei steigender Flanke übernommen }; /* template for a EDMA configuration */ /* Empfangen */ EDMA_Config configEDMARcv = { EDMA_FMKS(OPT, PRI, LOW) | // auf beide Queues verteilen EDMA_FMKS(OPT, ESIZE, 16BIT) | // Element size EDMA_FMKS(OPT, 2DS, NO) | // kein 2D-Transfer EDMA_FMKS(OPT, SUM, NONE) | // Quell-update mode -> FEST (McBSP)!!! EDMA_FMKS(OPT, 2DD, NO) | // 2kein 2D-Transfer EDMA_FMKS(OPT, DUM, INC) | // Ziel-update mode -> inkrementieren (ping/pong in buffer) EDMA_FMKS(OPT, TCINT,YES) | // EDMA interrupt erzeugen? EDMA_FMKS(OPT, TCC, OF(0)) | // Transfer complete code (TCC) EDMA_FMKS(OPT, LINK, YES) | // Link Parameter nutzen? EDMA_FMKS(OPT, FS, NO), // Frame Sync nutzen? EDMA_FMKS(SRC, SRC, OF(0)), // Quell-Adresse EDMA_FMK(CNT, FRMCNT, NULL) | // Anzahl Frames EDMA_FMK(CNT, ELECNT, BUFFER_LEN), // Anzahl Elemente
MCBSP_FMKS(PCR, FSXM, EXTERNAL) | // Framesync- Signal für Sender kommt von extern (Slave) MCBSP_FMKS(PCR, FSRM, EXTERNAL) | // Framesync- Signal für Empfänger kommt von extern (Slave) MCBSP_FMKS(PCR, CLKXM, INPUT) | // Takt für Sender kommt von extern (Slave) MCBSP_FMKS(PCR, CLKRM, INPUT) | // Takt für Empfänger kommt von extern (Slave) MCBSP_FMKS(PCR, CLKSSTAT, DEFAULT) | // unrelevant da PINS keine GPIOs MCBSP_FMKS(PCR, DXSTAT, DEFAULT) | // unrelevant da PINS keine GPIOs MCBSP_FMKS(PCR, FSXP, ACTIVEHIGH) | // Framesync senderseitig ist "activehigh" MCBSP_FMKS(PCR, FSRP, ACTIVEHIGH) | // Framesync empfängerseitig ist "activehigh" MCBSP_FMKS(PCR, CLKXP, FALLING) | // Datum wird bei fallender Flanke gesendet MCBSP_FMKS(PCR, CLKRP, RISING) // Datum wird bei steigender Flanke übernommen }; /* template for a EDMA configuration */ EDMA_Config configEDMARcv = { EDMA_FMKS(OPT, PRI, LOW) | // auf beide Queues verteilen EDMA_FMKS(OPT, ESIZE, 16BIT) | // Element size EIGEN!!!: Im Foliensatz so gefunden, bin aber nicht sicher, hat das überhaupt große Auswirkung? EDMA_FMKS(OPT, 2DS, NO) | // kein 2D-Transfer EDMA_FMKS(OPT, SUM, NONE) | // Quell-update mode -> FEST (McBSP)!!! EDMA_FMKS(OPT, 2DD, NO) | // 2kein 2D-Transfer EDMA_FMKS(OPT, DUM, INC) | // Ziel-update mode EIGEN!!!: Ziel-Adresse wird nicht aktualisiert, immer die selbe EDMA_FMKS(OPT, TCINT, YES) | // EDMA interrupt erzeugen? EIGEN!!!: EDMA muss Interrupts erzeugen! EDMA_FMKS(OPT, TCC, OF(0)) | // Transfer complete code (TCC) EDMA_FMKS(OPT, LINK, YES) | // Link Parameter nutzen? EDMA_FMKS(OPT, FS, NO), // Frame Sync nutzen? EDMA_FMKS(SRC, SRC, OF(0)), // Quell-Adresse EDMA_FMK (CNT, FRMCNT, NULL) | // Anzahl Frames EDMA_FMK (CNT, ELECNT, BUFFER_LEN), // Anzahl Elemente
void conf_EDMA(){ /* * Open EDMA channels to the REVT1 and XEVT1 interrupts * issued from the MCBSP periphery. The channels still * need to be configured properly with a parameterset * and another parameterset that fills the pong Buffer. */ hEDMATrx = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); /* * Aquire EDMA tables that hold the reload tables for both, * transmit and receive side bufferswitch. */ hEDMATrxPing = EDMA_allocTable(-1); hEDMATrxPong = EDMA_allocTable(-1); /* * Set the EDMA source address. On the receive side we use * the MCBSP source address and save it in the EDMA config * handle. For the transmit side we will have a fixed * destination but a variable source address, so we need to * set the destination to a fixed address! */ conf_EDMA_oBuf.dst = MCBSP_getXmtAddr(hMcBsp); /* * The next step is to find free Transfer complete codes, * save them to a variable so the EDMA hardware interrupt * is able to distinguish between the RX and TX complete * code. We *could* assign those as static codes, but it * is better coding practice to make it variable to allow * future expansion of the code. */ tccTrxPing = EDMA_intAlloc(-1); conf_EDMA_oBuf.opt |= EDMA_FMK(OPT, TCC, tccTrxPing); /* * Configure the transmit and receive channel to write in the * ping buffers. The function copies the struct into the * EDMA parameter RAM. This allows us to reuse the configs * to set up the reload configuration for the pong buffers. */ EDMA_config(hEDMATrx, &conf_EDMA_oBuf); EDMA_config(hEDMATrxPing, &conf_EDMA_oBuf); /* * Now we are ready to configure the reload parametersets * that will write to the pong buffers after the ping * buffer is filled with data. */ /* * First we need to set the destination and source of the * corresponding pong buffers for both sides. */ conf_EDMA_oBuf.src = (uint32_t)oBufPong; /* * We also need a transfer complete code for the second * configuration set to show that we indeed have finished * the transfer to the pong buffers and switch to ping. * To overwrite the ones written before we need to * overwrite the whole 32 OPT bits */ tccTrxPong = EDMA_intAlloc(-1); conf_EDMA_oBuf.opt = EDMA_FMKS(OPT, PRI, HIGH) | EDMA_FMKS(OPT, ESIZE, 32BIT) | EDMA_FMKS(OPT, 2DS, NO) | EDMA_FMKS(OPT, SUM, INC) | EDMA_FMKS(OPT, 2DD, NO) | EDMA_FMKS(OPT, DUM, NONE) | EDMA_FMKS(OPT, TCINT, YES) | EDMA_FMKS(OPT, TCC, OF(0)) | EDMA_FMKS(OPT, LINK, YES) | EDMA_FMKS(OPT, FS, NO); conf_EDMA_oBuf.opt |= EDMA_FMK(OPT, TCC, tccTrxPong); /* * Now we can write the pong buffer configs to the parameter RAM * tables we aquired before by using EDMA_config().. */ EDMA_config(hEDMATrxPong, &conf_EDMA_oBuf); /* * We now need to link the transfers so the EDMA fires an interrupt * whenever we finished a job and immediately starts to * fill the other buffer (ping -> pong -> ping). */ EDMA_link(hEDMATrx, hEDMATrxPing); EDMA_link(hEDMATrxPing, hEDMATrxPong); EDMA_link(hEDMATrxPong, hEDMATrxPing); /* * Now we take precautions and clear all * the interrupt sources so no interrupt * can fire because of some wiggling bits * caused by an unstable supply. */ EDMA_intClear(tccTrxPing); EDMA_intClear(tccTrxPong); /* * Lets enable the interrupts, but we aren't * done yet: There's still the global interrupt * switch to be toggled by enable_INT() after * we started the EDMA transfers. */ EDMA_intEnable(tccTrxPing); EDMA_intEnable(tccTrxPong); }