I have a fully functioning modem which uses an AIC23B codec connected through McBSP to the EDMA3 controller of a C6748. Basically like this:
AIC23B -> McBSP -> EDMA3 -> RAM -> ...
The EDMA setup looks like this:
#define SOC_MCBSP_1_CTRL_REGS (0x01D11000)
#define MCBSP_DRR (0x0)
#define MCBSP_DXR (0x4)
#define McBSP0_DRR ( SOC_MCBSP_0_CTRL_REGS + MCBSP_DRR )
#define McBSP0_DXR ( SOC_MCBSP_0_CTRL_REGS + MCBSP_DXR )
chan = EDMA_MCBSP0_TX_CH_INIT;
EDMA3_PARAM_SET(chan)->OPT = EDMA_OPT_TCINTEN | EDMA_OPT_TCC_MCBSP0_TX;
EDMA3_PARAM_SET(chan)->SRC = (uint32_t)(zero_buffer);
EDMA3_PARAM_SET(chan)->A_B_CNT = (uint32_t)(idle_zero_count << 16 |
sizeof( uint32_t) );
EDMA3_PARAM_SET(chan)->DST = McBSP0_DXR;
EDMA3_PARAM_SET(chan)->SRC_DST_BIDX = (uint32_t)(sizeof( uint32_t));
EDMA3_PARAM_SET(chan)->LINK_BCNTRLD = (uint32_t)(idle_zero_count << 16 |
(EDMA3_PARAM_BASE(EDMA_MCBSP0_TX_CH_LINK) & 0x0000FFFF));
EDMA3_PARAM_SET(chan)->SRC_DST_CIDX = (uint32_t)(0);
EDMA3_PARAM_SET(chan)->C_CNT = (uint32_t)(1);
chan = EDMA_MCBSP0_RX_CH_INIT;
EDMA3_PARAM_SET(chan)->OPT = EDMA_OPT_TCINTEN | EDMA_OPT_TCC_MCBSP0_RX;
EDMA3_PARAM_SET(chan)->SRC = McBSP0_DRR;
EDMA3_PARAM_SET(chan)->A_B_CNT = (uint32_t)(default_adc_block_size << 16 |
sizeof( uint32_t) );
EDMA3_PARAM_SET(chan)->DST = (uint32_t)(&EDMA_adc_buffer[0]);
EDMA3_PARAM_SET(chan)->SRC_DST_BIDX = (uint32_t)(sizeof( uint32_t) << 16);
EDMA3_PARAM_SET(chan)->LINK_BCNTRLD = (uint32_t)(default_adc_block_size<<16 |
(EDMA3_PARAM_BASE(EDMA_MCBSP0_RX_CH_LINK) & 0x0000FFFF));
EDMA3_PARAM_SET(chan)->SRC_DST_CIDX = (uint32_t)(0);
EDMA3_PARAM_SET(chan)->C_CNT = (uint32_t)(1);
The same for the LINK PaRAM sets. This uses a pink-ping buffer and works as expected.
However, I'd like to do some measurements on the signal path and have implemented analogue bypass in the AIC23B (i.e. loopback before the ADC/DAC - this works), but I'd also like to implement a local/analogue/audio loopback/pass-through after the ADC/DAC (i.e. RX -> TX). NOTE: This is not the digital loopback mode (DLB) of operation which is TX -> RX.
My plan is to feed the RX EDMA channel data directly back to the TX EDMA channel. Hence when the McBSP interrupt arrives, instead of changing the DST parameter of the LINK PaRAM of the RX channel to the next ping-pong buffer, I change it to the DST for the TX channel:
chan = EDMA_MCBSP1_RX_CH_LINK;
EDMA3_PARAM_SET(chan)->DST = McBSP0_DXR;
EDMA3_PARAM_SET(chan)->A_B_CNT = (uint32_t)(ctrl->next_adc_block_size << 16 |
sizeof( uint32_t) );
I have a Keysight MSO-X-3024A which has a sine wave generator connected to RX and the scope to the TX. What happens when I enable this loopback mode, is that when the first interrupt arrives, data will be in the (e.g.) 'ping' buffer, and the LINK PaRAM set is configured as above (the self PaRAM set now has DST = 'pong' buffer). When the second interrupt arrives, data will be in the 'pong' buffer, and the LINK set is configured as above again (the self PaRAM set now has DST = McBSP0_DXR). But then no more interrupts arrive!
I could have understood that with this setup no data was transmitted to the TX channel (I can't say for sure that data is or isn't sent to the TX channel - my scope is too limited (or my knowledge of it)), but I don't understand why the interrupts should stop. The docs doesn't explicitly disallow direct transfer between to memory mapped regions (DRR -> DXR) as far as I have been able to determine. If this is correct, what can be wrong? Any other clever ideas on how to effectively implement such a loopback feature?
I'm using SYSBIOS 6.35.4.50 and XDCtools 3.25.3.72.