Other Parts Discussed in Thread: ADS1278, ADS1274
Hello,
I'm trying to connect a Concerto to an ADS1278 A to D. I have my init code for the McBSP and the DMA shown below.
The ADS1278 is sending 4 channels of 24 bit data after every frame sync signal sent from the Concerto. I can see that on the scope.
The SPCR1 register in the McBSP becomes 0x3 and then 0x7, meaning data is ready. But if I put a breakpoint in the DMA ISR it never gets hit.
When I stop execution, DMACH2_CONTROL is 0x0100, which means the peripheral interrupt flag is true and the RUNSTS bit = 0. DMACH2_TRANSFER_COUNT is 0. It seems like the transfer is complete.
In the PIE control register, PIEIER7 = 2, and CPU interrupt 7 is enabled.
Why am I not getting an interrupt? Does the DMA init look correct? I've looked at all the McBSP and DMA example code and I'm still lost.
Thank you,
Joel
void InitMcbsp(void)
{
// Reset FS generator, sample rate generator & transmitter
// Reset Receiver, Right justify word
//
// Disable all McBSP interrupts
McbspaRegs.MFFINT.all=0x0;
// Single-phase frame, No companding (Receive)
McbspaRegs.RCR2.all=0x0;
// 4 words per frame since there are 4 ADC channels being read simultaneously
McbspaRegs.RCR1.bit.RFRLEN1 = 3; // The register is loaded with the number of words minus 1
// 24 bit words
McbspaRegs.RCR1.bit.RWDLEN1 = 4;
//
// Receiver's frame sync signal is generated internally (output from the Concerto to the ADC)
// Receiver's clock generated internally (also output to the ADC)
//
McbspaRegs.PCR.bit.FSRM = 1;
McbspaRegs.PCR.bit.CLKRM = 1;
McbspaRegs.PCR.bit.SCLKME = 0;
//
// CLKSM = 1 and SCLKME=0, clock source for sample rate generator is low speed clock (SYSCLKOUT / LSPCLK, which is 75MHz / 4 = 18.75MHz in our case)
// Let the frame period FPER = 200 CLKG periods. Time between frame sync pulses will be 200 x 1/18.75MHz = 10.67uS
//
McbspaRegs.SRGR2.bit.CLKSM = 1;
McbspaRegs.SRGR2.bit.FPER = 199; // Register = 200 - 1
//
// Reset TX and RX
// Enable interrupts for RX so it will trigger the transfer out of the DRR1 and DRR2 registers
McbspaRegs.SPCR2.bit.XRST = 0;
McbspaRegs.SPCR1.bit.RRST = 0;
McbspaRegs.MFFINT.bit.RINT = 1;
}
void StartMcBSP(void)
{
// Enable the sample rate generator
// Wait at least 2 SRG clock cycles
// Release RX from Reset
// Frame Sync Generator reset
//
McbspaRegs.SPCR2.bit.GRST=1;
DELAY_US(20);
McbspaRegs.SPCR1.bit.RRST=1;
McbspaRegs.SPCR2.bit.FRST=1;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void InitDMA(void)
{
EALLOW;
DmaRegs.DMACTRL.bit.HARDRESET = 1;
__asm(" NOP"); // Only 1 NOP needed per Design
// Allow DMA to run free on emulation suspend
DmaRegs.DEBUGCTRL.bit.FREE = 0; // 0 = Halt DMA during emulation halt. 1 = Run free.
//
// Enable DMA channel 2, it will be from McBSP-A receive
//
// To accommodate a McBSP data size of > 16-bits, the
// DMA will read 16 bits from McBSP's data receive register 1 and 16 bits from McBSP receive register 2.
//
// Transfer 2 16-bit words per burst. There are 2 words per adc channel (to get 24 bits).
// Increment the destination address by 1 between words
DmaRegs.CH2.BURST_SIZE.all = 1; // 2 words per burst
DmaRegs.CH2.SRC_BURST_STEP = 1; // Add 1 to the 16 bit source address between words
DmaRegs.CH2.DST_BURST_STEP = 1; // Add 1 to the destination address. The lower address will hold the most significant bits read from DRR2. The higher address will hold the bits from DRR1.
//
DmaRegs.CH2.TRANSFER_SIZE = 3; // = (8 / 2) - 1; There are eight 16 bit words and we're doing 32 bit DMA transfers.
//
// After each burst:
// Subtract 1 from the source address (back to DRR2)
// Add 1 to the destination address: to move to the next word
DmaRegs.CH2.SRC_TRANSFER_STEP = 0xFFFF;
DmaRegs.CH2.DST_TRANSFER_STEP = 1;
//
// Receiver data source and destination:
// McBSP (source) -> DMA -> ADC data buffer (destination)
// Set the source to the McBSP DRR2 (data receive register, upper 16 bits)
// The lower 16 bits will be read from the DRR1 register as part of each burst.
DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all;
DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &HiResADCdata[0];
//
// Clear sync flag and error flag
//
DmaRegs.CH2.CONTROL.bit.ERRCLR = 1;
//
// Do not use the wrap function
// Set the wrap size to the maximum value
// which in effect disables it.
//
DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF;
DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF;
//
// Enable channel interrupt at end of transfer
// Peripheral interrupt for receive is McBSP MREVTA
// McBSP receive buffer is full
// Clear any interrupt flags
//
DmaRegs.CH2.MODE.bit.CHINTE = 1;
DmaRegs.CH2.MODE.bit.CHINTMODE = 1;
DmaRegs.CH2.MODE.bit.PERINTE = 1;
DmaRegs.CH2.MODE.bit.PERINTSEL = DMA_MREVTA;
DmaRegs.CH2.MODE.bit.ONESHOT = 1;
DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;
EnableInterrupt(INT_DMA_CH2);
// Enable DMA channel 2
DmaRegs.CH2.CONTROL.bit.RUN = 1;
EDIS;
}