/* * initEdma() - Initialize the DMA controller. Use linked transfers to * automatically transition from ping to pong and visa-versa. */ void initEdma(void) { /* Configure transmit channel */ hEdmaXmt = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); // get hEdmaXmt handle and reset channel hEdmaReloadXmtPing = EDMA_allocTable(-1); // get hEdmaReloadXmtPing handle hEdmaReloadXmtPong = EDMA_allocTable(-1); // get hEdmaReloadXmtPong handle gEdmaConfigXmt.dst = MCBSP_getXmtAddr(hMcbsp1); // set the desination address to McBSP1 DXR gXmtChan = EDMA_intAlloc(-1); // get an open TCC gEdmaConfigXmt.opt |= EDMA_FMK(OPT,TCC,gXmtChan); // set TCC to gXmtChan EDMA_config(hEdmaXmt, &gEdmaConfigXmt); // then configure the registers EDMA_config(hEdmaReloadXmtPing, &gEdmaConfigXmt); // and the reload for Ping gEdmaConfigXmt.src = EDMA_SRC_OF(gBufferXmtPong); // change the structure to have a source of Pong EDMA_config(hEdmaReloadXmtPong, &gEdmaConfigXmt); // and configure the reload for Pong EDMA_link(hEdmaXmt,hEdmaReloadXmtPong); // link the regs to Pong EDMA_link(hEdmaReloadXmtPong,hEdmaReloadXmtPing); // link Pong to Ping EDMA_link(hEdmaReloadXmtPing,hEdmaReloadXmtPong); // and link Ping to Pong /* Configure receive channel */ hEdmaRcv = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); // get hEdmaRcv handle and reset channel hEdmaReloadRcvPing = EDMA_allocTable(-1); // get hEdmaReloadRcvPing handle hEdmaReloadRcvPong = EDMA_allocTable(-1); // get hEdmaReloadRcvPong handle gEdmaConfigRcv.src = MCBSP_getRcvAddr(hMcbsp1); // and the desination address to McBSP1 DXR gRcvChan = EDMA_intAlloc(-1); // get an open TCC gEdmaConfigRcv.opt |= EDMA_FMK(OPT,TCC,gRcvChan); // set TCC to gRcvChan EDMA_config(hEdmaRcv, &gEdmaConfigRcv); // then configure the registers EDMA_config(hEdmaReloadRcvPing, &gEdmaConfigRcv); // and the reload for Ping gEdmaConfigRcv.dst = EDMA_DST_OF(gBufferRcvPong); // change the structure to have a destination of Pong EDMA_config(hEdmaReloadRcvPong, &gEdmaConfigRcv); // and configure the reload for Pong EDMA_link(hEdmaRcv,hEdmaReloadRcvPong); // link the regs to Pong EDMA_link(hEdmaReloadRcvPong,hEdmaReloadRcvPing); // link Pong to Ping EDMA_link(hEdmaReloadRcvPing,hEdmaReloadRcvPong); // and link Ping to Pong /* Enable interrupts in the EDMA controller */ EDMA_intClear(gXmtChan); EDMA_intClear(gRcvChan); // clear any possible spurious interrupts EDMA_intEnable(gXmtChan); // enable EDMA interrupts (CIER) EDMA_intEnable(gRcvChan); // enable EDMA interrupts (CIER) EDMA_enableChannel(hEdmaXmt); // enable EDMA channel EDMA_enableChannel(hEdmaRcv); // enable EDMA channel /* Do a dummy write to generate the first McBSP transmit event */ MCBSP_write(hMcbsp1, 0); }
/* 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 EDMA_FMKS(DST, DST, OF(0)), // Dest address EDMA_FMKS(IDX, FRMIDX, DEFAULT) | // Frame index value EDMA_FMKS(IDX, ELEIDX, DEFAULT), // Element index value EDMA_FMK (RLD, ELERLD, NULL) | // Reload element EDMA_FMK (RLD, LINK, NULL) // Reload link }; /* Receive side EDMA configuration */ EDMA_Config gEdmaConfigRcv = { EDMA_FMKS(OPT, PRI, HIGH) | // Priority EDMA_FMKS(OPT, ESIZE, 16BIT) | // Element size
void config_EDMA(void) { LOG_printf(&myLog, "config EDMA begin"); // EIGEN!!!: Konfiguration Recieve Ping /* Konfiguration der EDMA zum Lesen*/ hEdmaRcv = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); // EDMA Channel for REVT1 hEdmaReloadRcvPing = EDMA_allocTable(-1); // Reload-Parameters Ping hEdmaReloadRcvPong = EDMA_allocTable(-1); // Reload-Parameters Pong 2 Param Sets needed (Ping & Pong) -> Pong write on my own hEdmaReloadRcvPeng = EDMA_allocTable(-1); // Reload-Parameters Peng configEDMARcv.src = MCBSP_getRcvAddr(hMcbsp); // source addr //Recieve Ping tccRcvPing = EDMA_intAlloc(-1); // next available TCC configEDMARcv.opt |= EDMA_FMK(OPT,TCC,tccRcvPing); // Grundkonfiguration EDMA-channel configEDMARcv.dst = ((int)Buffer_in_ping)/* & 0xFFFF*/; // Zieladresse //configEDMARcv.dst = ((short)Buffer_in_ping)/* & 0xFFFF*/; // Zieladresse /* Erster Transfer und Reload-Ping */ EDMA_config(hEdmaRcv, &configEDMARcv); EDMA_config(hEdmaReloadRcvPing, &configEDMARcv); //Recieve Pong tccRcvPong = EDMA_intAlloc(-1); // next available TCC configEDMARcv.opt |= EDMA_FMK(OPT,TCC,tccRcvPong); // Grundkonfiguration EDMA-channel configEDMARcv.dst = ((int)Buffer_in_pong)/* & 0xFFFF*/; // Zieladresse //configEDMARcv.dst = ((short)Buffer_in_pong)/* & 0xFFFF*/; // Zieladresse /* Erster Transfer und Reload-Ping */ EDMA_config(hEdmaReloadRcvPong, &configEDMARcv); //Recieve Peng tccRcvPeng = EDMA_intAlloc(-1); // next available TCC configEDMARcv.opt |= EDMA_FMK(OPT,TCC,tccRcvPeng); // Grundkonfiguration EDMA-channel configEDMARcv.dst = ((int)Buffer_in_peng)/* & 0xFFFF*/; // Zieladresse //configEDMARcv.dst = ((short)Buffer_in_peng)/* & 0xFFFF*/; // Zieladresse /* Erster Transfer und Reload-Ping */ EDMA_config(hEdmaReloadRcvPeng, &configEDMARcv); /* link transfers ping -> pong -> peng -> ping */ EDMA_link(hEdmaRcv,hEdmaReloadRcvPong); EDMA_link(hEdmaReloadRcvPong,hEdmaReloadRcvPeng); EDMA_link(hEdmaReloadRcvPeng,hEdmaReloadRcvPing); EDMA_link(hEdmaReloadRcvPing,hEdmaReloadRcvPong); /* do you want to hear music? */ // Gleiche Konfiguration wie oben für Lesen muss nun für Schreiben angewendet werden hEdmaXmt = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); // EDMA Channel for REVT1 hEdmaReloadXmtPing = EDMA_allocTable(-1); // Reload-Parameters Ping hEdmaReloadXmtPong = EDMA_allocTable(-1); // Reload-Parameters Pong 2 Param Sets needed (Ping & Pong) -> Pong write on my own hEdmaReloadXmtPeng = EDMA_allocTable(-1); // Reload-Parameters Peng configEDMAXmt.dst = MCBSP_getXmtAddr(hMcbsp); // destination addr //Transmit Ping tccXmtPing = EDMA_intAlloc(-1); // next available TCC configEDMAXmt.opt |= EDMA_FMK(OPT,TCC,tccXmtPing); // Grundkonfiguration EDMA-channel configEDMAXmt.src = ((int)Buffer_out_ping)/* & 0xFFFF*/; // Quelladresse //configEDMAXmt.src = ((short)Buffer_out_ping)/* & 0xFFFF*/; // Quelladresse /* Erster Transfer und Reload-Ping */ EDMA_config(hEdmaXmt, &configEDMAXmt); EDMA_config(hEdmaReloadXmtPing, &configEDMAXmt); //Transmit Pong tccXmtPong = EDMA_intAlloc(-1); // next available TCC configEDMAXmt.opt |= EDMA_FMK(OPT,TCC,tccXmtPong); // Grundkonfiguration EDMA-channel configEDMAXmt.src = ((int)Buffer_out_pong)/* & 0xFFFF*/; // Quelladresse //configEDMAXmt.src = ((short)Buffer_out_pong)/* & 0xFFFF*/; // Quelladresse /* Erster Transfer und Reload-Ping */ EDMA_config(hEdmaReloadXmtPong, &configEDMAXmt); //Transmit Peng tccXmtPeng = EDMA_intAlloc(-1); // next available TCC configEDMAXmt.opt |= EDMA_FMK(OPT,TCC,tccXmtPeng); // Grundkonfiguration EDMA-channel configEDMAXmt.src = ((int)Buffer_out_peng)/* & 0xFFFF*/; // Quelladresse //configEDMAXmt.src = ((short)Buffer_out_peng)/* & 0xFFFF*/; // Quelladresse /* Erster Transfer und Reload-Ping */ EDMA_config(hEdmaReloadXmtPeng, &configEDMAXmt); /* link transfers ping -> pong -> ping */ EDMA_link(hEdmaXmt,hEdmaReloadXmtPong); EDMA_link(hEdmaReloadXmtPong,hEdmaReloadXmtPeng); EDMA_link(hEdmaReloadXmtPeng,hEdmaReloadXmtPing); EDMA_link(hEdmaReloadXmtPing,hEdmaReloadXmtPong); /* enable EDMA TCC */ //recieve ping EDMA_intClear(tccRcvPing); EDMA_intEnable(tccRcvPing); //recieve pong EDMA_intClear(tccRcvPong); EDMA_intEnable(tccRcvPong); //recieve peng EDMA_intClear(tccRcvPeng); EDMA_intEnable(tccRcvPeng); //transmit ping EDMA_intClear(tccXmtPing); EDMA_intEnable(tccXmtPing); //transmit pong EDMA_intClear(tccXmtPong); EDMA_intEnable(tccXmtPong); //transmit peng EDMA_intClear(tccXmtPeng); EDMA_intEnable(tccXmtPeng); /* which EDMAs do we have to enable? */ EDMA_enableChannel(hEdmaRcv); EDMA_enableChannel(hEdmaXmt); LOG_printf(&myLog, "config EDMA end"); }
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 (Uint32)Buffer_in_ping, // Ziel-Adresse Zur Laufzeit zu Pong-Adresse ändern und selbe Konfiguration verwenden? EDMA_FMKS(IDX, FRMIDX, DEFAULT) | // Frame index Wert EDMA_FMKS(IDX, ELEIDX, DEFAULT), // Element index Wert EDMA_FMK (RLD, ELERLD, NULL) | // Reload Element EDMA_FMK (RLD, LINK, NULL) // Reload Link }; EDMA_Config configEDMAXmt = /* Parameter nochmal überprüfen!!!!!!! */ { 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?
void config_EDMA(void) { /* Konfiguration der EDMA zum Lesen*/ hEdmaRcv = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); // EDMA Kanal für das Event REVT1 hEdmaRcvRelPing = EDMA_allocTable(-1); // einen Reload-Parametersatz für Ping hEdmaRcvRelPong = EDMA_allocTable(-1); // einen Reload-Parametersatz für Pong configEDMARcv.src = MCBSP_getRcvAddr(hMcbsp); // Quell-Adresse zum Lesen tccRcvPing = EDMA_intAlloc(-1); // nächsten freien Transfer-Complete-Code Ping tccRcvPong = EDMA_intAlloc(-1); // nächsten freien Transfer-Complete-Code Pong configEDMARcv.opt |= EDMA_FMK(OPT,TCC,tccRcvPing); // dann der Grundkonfiguration des EDMA Empfangskanals zuweisen /* ersten Transfer und Reload-Ping mit ConfigPing konfigurieren */ EDMA_config(hEdmaRcv, &configEDMARcv); EDMA_config(hEdmaRcvRelPing, &configEDMARcv); /* braucht man auch noch andere EDMA-Konfigurationen fuer das Lesen? ja -> pong */ configEDMARcv.opt |= EDMA_FMK(OPT,TCC,tccRcvPong); configEDMARcv.dst = (Uint32)Buffer_in_pong ; EDMA_config(hEdmaRcvRelPong, &configEDMARcv); /* Transfers verlinken ping -> pong -> ping */ EDMA_link(hEdmaRcv, hEdmaRcvRelPong); /* noch mehr verlinken? */ EDMA_link(hEdmaRcvRelPong, hEdmaRcvRelPing); EDMA_link(hEdmaRcvRelPing, hEdmaRcvRelPong); /* muss man mittels EDMA auch schreiben? */ /* Konfiguration der EDMA zum Schreiben */ hEdmaXmt = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); // EDMA Kanal für das Event REVT1 hEdmaXmtRelPing = EDMA_allocTable(-1); // einen Reload-Parametersatz für Ping hEdmaXmtRelPong = EDMA_allocTable(-1); // einen Reload-Parametersatz für Pong configEDMAXmt.dst = MCBSP_getXmtAddr(hMcbsp); // Ziel-Adresse zum Schreiben tccXmtPing = EDMA_intAlloc(-1); // nächsten freien Transfer-Complete-Code Ping tccXmtPong = EDMA_intAlloc(-1); // nächsten freien Transfer-Complete-Code Pong configEDMAXmt.opt |= EDMA_FMK(OPT,TCC,tccXmtPing); // dann der Grundkonfiguration des EDMA Sendekanal zuweisen /* ersten Transfer und Reload-Ping mit ConfigPing konfigurieren */ EDMA_config(hEdmaXmt, &configEDMAXmt); EDMA_config(hEdmaXmtRelPing, &configEDMAXmt); /* braucht man auch noch andere EDMA-Konfigurationen fuer das Schreiben? ja -> pong */ configEDMAXmt.opt |= EDMA_FMK(OPT,TCC,tccXmtPong); configEDMAXmt.src = (Uint32)Buffer_out_pong ; EDMA_config(hEdmaXmtRelPong, &configEDMAXmt); /* Transfers verlinken ping -> pong -> ping */ EDMA_link(hEdmaXmt, hEdmaXmtRelPong); /* noch mehr verlinken? */ EDMA_link(hEdmaXmtRelPong, hEdmaXmtRelPing); EDMA_link(hEdmaXmtRelPing, hEdmaXmtRelPong); /* EDMA TCC-Interrupts freigeben */ EDMA_intClear(tccRcvPing); EDMA_intEnable(tccRcvPing); EDMA_intClear(tccRcvPong); EDMA_intEnable(tccRcvPong); /* sind das alle? nein -> pong und alle für Sendeseite */ EDMA_intClear(tccXmtPing); EDMA_intEnable(tccXmtPing); EDMA_intClear(tccXmtPong); EDMA_intEnable(tccXmtPong); /* EDMA starten, wen alles? */ EDMA_enableChannel(hEdmaRcv); EDMA_enableChannel(hEdmaXmt); }
void DSK6713_configure_AIC23() { /* Configure McBSP0 as control interface for aic23 */ MCBSP_Handle MCBSP0_handle; MCBSP0_handle = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET); MCBSP_config(MCBSP0_handle, &MCBSP0_config); MCBSP_start(MCBSP0_handle, MCBSP_XMIT_START | MCBSP_SRGR_START | MCBSP_SRGR_START, 220); set_aic23_register(MCBSP0_handle, RESET_REGISTER, 0x0000); set_aic23_register(MCBSP0_handle, POWER_DOWN_CONTROL, 0x0000); set_aic23_register(MCBSP0_handle, LEFT_LINE_INPUT_CHANNEL_VOLUME, 0x0017); set_aic23_register(MCBSP0_handle, RIGHT_LINE_INPUT_CHANNEL_VOLUME, 0x0017); set_aic23_register(MCBSP0_handle, LEFT_CHANNEL_HEADPHONE_VOLUME, 0x00f9); set_aic23_register(MCBSP0_handle, RIGHT_CHANNEL_HEADPHONE_VOLUME, 0x00f9); set_aic23_register(MCBSP0_handle, ANALOG_AUDIO_PATH, 0x0011); // 00001 0010 set_aic23_register(MCBSP0_handle, DIGITAL_AUDIO_PATH, 0x0000); // 000000000 set_aic23_register(MCBSP0_handle, DIGITAL_AUDIO_INTERFACE_FORMAT, 0x0043); //0 0100 0001 set_aic23_register(MCBSP0_handle, SAMPLE_RATE_CONTROL, 0x000d); // 01100 set_aic23_register(MCBSP0_handle, DIGITAL_INTERFACE_ACTIVATION, 0x0001); /* Configure McBSP1 as data interface for aic23 */ MCBSP_Handle MCBSP1_handle; MCBSP1_handle = MCBSP_open(MCBSP_DEV1, MCBSP_OPEN_RESET); MCBSP_config(MCBSP1_handle, &MCBSP1_config); MCBSP_start(MCBSP1_handle, MCBSP_XMIT_START|MCBSP_RCV_START|MCBSP_SRGR_FRAMESYNC|MCBSP_SRGR_START, 220); /* Configure receive EDMA */ EDMA_Handle hEdmaRcv; EDMA_Handle hEdmaRcvA; EDMA_Handle hEdmaRcvB; hEdmaRcv = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); hEdmaRcvA = EDMA_allocTable(-1); hEdmaRcvB = EDMA_allocTable(-1); gEdmaRcvConfig.src = MCBSP_getRcvAddr(MCBSP1_handle); // Get address of DRR gTccRcvChan = EDMA_intAlloc(-1); // get next free transfer complete code gEdmaRcvConfig.opt |= EDMA_FMK(OPT, TCC, gTccRcvChan); EDMA_config(hEdmaRcv, &gEdmaRcvConfig); EDMA_config(hEdmaRcvA, &gEdmaRcvConfig); gEdmaRcvConfig.dst = EDMA_DST_OF(gRcvBufferB); EDMA_config(hEdmaRcvB, &gEdmaRcvConfig); EDMA_link(hEdmaRcv, hEdmaRcvB); EDMA_link(hEdmaRcvB, hEdmaRcvA); EDMA_link(hEdmaRcvA, hEdmaRcvB); /* Configure transmit EDMA */ EDMA_Handle hEdmaXmt; EDMA_Handle hEdmaXmtA; EDMA_Handle hEdmaXmtB; hEdmaXmt = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); hEdmaXmtA = EDMA_allocTable(-1); hEdmaXmtB = EDMA_allocTable(-1); gEdmaXmtConfig.dst = MCBSP_getXmtAddr(MCBSP1_handle); // Get address of DXR gTccXmtChan = EDMA_intAlloc(-1); // get next free transfer complete code gEdmaXmtConfig.opt |= EDMA_FMK(OPT, TCC, gTccXmtChan); EDMA_config(hEdmaXmt, &gEdmaXmtConfig); EDMA_config(hEdmaXmtA, &gEdmaXmtConfig); gEdmaXmtConfig.src = EDMA_DST_OF(gXmtBufferB); // set source to buffer B EDMA_config(hEdmaXmtB, &gEdmaXmtConfig); EDMA_link(hEdmaXmt, hEdmaXmtB); EDMA_link(hEdmaXmtB, hEdmaXmtA); EDMA_link(hEdmaXmtA, hEdmaXmtB); EDMA_intClear(gTccRcvChan); EDMA_intClear(gTccXmtChan); EDMA_intEnable(gTccRcvChan); EDMA_intEnable(gTccXmtChan); gBufferState.cpuBufferState = StateB; // inittial cpu buffer state EDMA_enableChannel(hEdmaRcv); EDMA_enableChannel(hEdmaXmt); IRQ_clear(IRQ_EVT_EDMAINT); IRQ_enable(IRQ_EVT_EDMAINT); MCBSP_write(MCBSP1_handle, 0x00); }
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); }