I've incorporated the mcbsp dma loopback example in to my project. Basically at the end of an ISR I want to start the dma-mcbsp process where 4 words of 16-bit length are sent. I want 4 words per frame and I want the clock to go low when I'm not using the mcbsp. I'm using DMA ch3 for Tx and DMA Ch4 for Rx. My problem is that when I change the frame length I get some weird results. Also I'm wondering if I'm starting/stopping the mcbsp in the proper way. I've attached some scope shots.
I'm noticing that when I use
McbspaRegs.RCR1.bit.RFRLEN1= 0
McbspaRegs.XCR1.bit.XFRLEN1 = 0
the received data is correct but my clock stays on longer than 64 cycles (4 words * 16 bits). I guess this is ok but I want to use 4 words per frame.
If I use
McbspaRegs.RCR1.bit.RFRLEN1 = 3;
McbspaRegs.XCR1.bit.XFRLEN1 = 3;
The clock stops pulsing before the end of the last word and the received data is offset in memory.
In either case I get 4 frame synch pulses, whereas I was expecting one frame sync pulse in the second case.
At the end of my ISR I do the following to start the dma-mcbsp:
EALLOW;
McbspaRegs.SPCR2.bit.GRST = 1;
DmaRegs.CH3.CONTROL.bit.RUN = 1;
DmaRegs.CH4.CONTROL.bit.RUN = 1;
EDIS;
Here's the dma isr
//*****************************************************************************
// DMA Channel 3 interrupt service routine for MCBSP Tx
//*****************************************************************************
__interrupt void local_DINTCH3_ISR(void)
{
EALLOW;
DmaRegs.CH3.CONTROL.bit.HALT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
MCBSP_DMA_CH3_Count++;
EDIS;
return;
}
//*****************************************************************************
// DMA Channel 4 interrupt service routine for MCBSP Rx
//*****************************************************************************
__interrupt void local_DINTCH4_ISR(void)
{
EALLOW;
DmaRegs.CH4.CONTROL.bit.HALT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
McbspaRegs.SPCR2.bit.GRST = 0; //reset sample generator, will get set in another isr
//reset so mcbsp clk goes low until next tx
MCBSP_DMA_CH4_Count++;
EDIS;
return;
}
Here's my dma and mcbsp init functions:
void init_dma_mcbsp(void)
{
EALLOW;
DmaRegs.DMACTRL.bit.HARDRESET = 1;
__asm(" NOP"); // Only 1 NOP needed per Design
//
// Enable channel 3: will be McBSP-A transmit
// Enable channel 4, will be McBSP-A receive
//
DmaRegs.CH3.MODE.bit.CHINTE = 0; // disables ch int
DmaRegs.CH4.MODE.bit.CHINTE = 0;
//
// 1 word/burst
// For McBSP burst step must be 0 (no increment)
//
DmaRegs.CH3.BURST_SIZE.all = 0;
DmaRegs.CH3.SRC_BURST_STEP = 0;
DmaRegs.CH3.DST_BURST_STEP = 0;
DmaRegs.CH4.BURST_SIZE.all = 0;
DmaRegs.CH4.SRC_BURST_STEP = 0;
DmaRegs.CH4.DST_BURST_STEP = 0;
//
// Interrupt every frame (TRANSFER_BUFFER_SIZE-1 bursts/transfer)
//
DmaRegs.CH3.TRANSFER_SIZE = MCBSP_TX_BUFFER_SIZE-1;
DmaRegs.CH4.TRANSFER_SIZE = MCBSP_TX_BUFFER_SIZE-1;
//
// For transmit, after each burst:
// After each transfer, step to the next source word
// Do not move the destination address
// Set the source to the start of the sdata buffer
// Set the destination to the McBSP DXR1
//
DmaRegs.CH3.SRC_TRANSFER_STEP = 1;
DmaRegs.CH3.DST_TRANSFER_STEP = 0;
//
// For receive, after each burst:
// Do not move the source address
// After each transfer, step to the next destination word
//
DmaRegs.CH4.SRC_TRANSFER_STEP = 0;
DmaRegs.CH4.DST_TRANSFER_STEP = 1;
//
// Clear the McBSP peripheral interrupt, sync, and error flags
//
DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1;
DmaRegs.CH3.CONTROL.bit.ERRCLR = 1;
DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1;
DmaRegs.CH3.CONTROL.bit.ERRCLR = 1;
//
// Do not use the wrap function
// Set the wrap size to the maximum value
// which in effect disables it.
//
DmaRegs.CH3.DST_WRAP_SIZE = 0xFFFF;
DmaRegs.CH3.SRC_WRAP_SIZE = 0xFFFF;
DmaRegs.CH4.DST_WRAP_SIZE = 0xFFFF;
DmaRegs.CH4.SRC_WRAP_SIZE = 0xFFFF;
//
// Enable channel interrupt at end of transfer
// Interrupt at end of the transfer (mode)
// Enable peripheral interrupt event
// Peripheral interrupt for transfer is McBSP MXSYNCA
// Peripheral interrupt for receive is McBSP MREVTA
// Clear any interrupt flags
//
DmaRegs.CH3.MODE.bit.CHINTE = 1;
DmaRegs.CH3.MODE.bit.CHINTMODE = 1;
DmaRegs.CH3.MODE.bit.PERINTE = 1;
DmaRegs.CH3.MODE.bit.PERINTSEL = DMA_MXEVTA;
DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1;
DmaRegs.CH4.MODE.bit.CHINTE = 1;
DmaRegs.CH4.MODE.bit.CHINTMODE = 1;
DmaRegs.CH4.MODE.bit.PERINTE = 1;
DmaRegs.CH4.MODE.bit.PERINTSEL = DMA_MREVTA;
DmaRegs.CH4.CONTROL.bit.PERINTCLR = 1;
EDIS;
}
//*****************************************************************************
// Initialize the McBSP.
//*****************************************************************************
void mcbsp_init_dlb(void)
{
// Reset FS generator, sample rate generator & transmitter
// Reset Receiver, Right justify word
// Enable digital loopback (DLB) mode
// Comment out for non-DLB mode
//todo: disable loopback mode
McbspaRegs.SPCR2.all=0x0000;
McbspaRegs.SPCR1.all=0x0000;
McbspaRegs.SPCR1.bit.DLB = 1;
//
// Disable all McBSP interrupts
McbspaRegs.MFFINT.all=0x0;
McbspaRegs.RCR2.all=0x0; // single phase Rx frame
McbspaRegs.RCR1.bit.RFRLEN1 = 0; // Rx frame length minus 1
McbspaRegs.RCR1.bit.RWDLEN1 = 2; // Rx word length is 16 bits
McbspaRegs.XCR2.all=0x0; // single phase Tx frame
McbspaRegs.XCR1.bit.XFRLEN1 = 0; // Tx frame length minus 1
McbspaRegs.XCR1.bit.XWDLEN1 = 2; // Tx word length is 16 bits
//
// CLKSM=1 (If SCLKME=0, i/p clock to SRG is LSPCLK)
// FPER = 32 CLKG periods
//
McbspaRegs.SRGR2.bit.CLKSM = 1; // sample rate generator clock taken from LSPCLK signal or MCLKX pin
McbspaRegs.SRGR2.bit.FPER = 255; // FPER+1 is the period between frame sync pulses
//
// Frame Width = 1 CLKG period
// CLKG frequency = LSPCLK/(CLKGDV+1)
McbspaRegs.SRGR1.bit.FWID = 0;
McbspaRegs.SRGR1.bit.CLKGDV = 0;
//
// FSX generated internally, FSR derived from an external source
// CLKX generated internally, CLKR derived from an external source
//
McbspaRegs.PCR.bit.FSXM = 1;
McbspaRegs.PCR.bit.CLKXM = 1;
//
// Enable the sample rate generator
// Wait at least 2 SRG clock cycles
// Release TX from Reset
// Release RX from Reset
// Frame Sync Generator reset
//
McbspaRegs.SPCR2.bit.GRST=1;
delay_loop();
McbspaRegs.SPCR2.bit.XRST=1;
McbspaRegs.SPCR1.bit.RRST=1;
McbspaRegs.SPCR2.bit.FRST=1;
}
Thank you