Hi,
We got an issue with transmitting data through mcbsp. We are trying to send 40 bits frame with two 20 bits words. We found that the data was being duplicated in the transmitted frame about once every two mins when we were trying to transmit 191 frames in 5Hz. Please check the initialization and writing function as the following.
void McBspDriver::InitMcBsp(McBspPort port)
{
Uint32 mcBspBaseAddr = PortToMcBspBaseAddress(port);
OMAP_MCBSP_REGS* mcBspRegs = (OMAP_MCBSP_REGS*) mcBspBaseAddr;
EnableClocks(port);
PinMux(port); // Configure pad multiplexing register fields for external pins
// Reset the McBSP module
mcBspRegs->SPCR1 &= ~MCBSP_SPCR1_RRST_RSTCLR;
mcBspRegs->SPCR2 &= ~MCBSP_SPCR2_FRST_RSTCLR & ~MCBSP_SPCR2_GRST_RSTCLR & ~MCBSP_SPCR2_XRST_RSTCLR;
//Table 21-24. McBSP Configuration in Function of the SRG Clock Source Selected
//Master Transmitter and Slave Receiver
mcBspRegs->PCR |= MCBSP_PCR_CLKXM | MCBSP_PCR_FSXM;
// Signal on mcbsp_clkr pin
// Table 21-25. Input Clock Selection for Sample Rate Generator
// mcBspRegs->PCR |= MCBSP_PCR_SCLKME;
// mcBspRegs->SRGR2 &= ~MCBSP_SRGR2_CLKSM;
// McBSPi_ICLK clock
mcBspRegs->PCR &= ~MCBSP_PCR_SCLKME;
mcBspRegs->SRGR2 |= MCBSP_SRGR2_CLKSM;
//Internal FSX is driven by the SRG FSG.
//Table 21-32. How FSXM and FSGM Select the Source of Transmit Frame-Sync Pulses
mcBspRegs->SRGR2 &= ~MCBSP_SRGR2_FSGM; // FPER and FWID are used to determine the frame synchronization period and width
mcBspRegs->SRGR2 |= MCBSP_SRGR2_FPER(0x27); // Frame Period = 40. This value + 1 determines when the next frame-sync signal becomes active
mcBspRegs->SRGR1 |= MCBSP_SRGR1_CLKGDV(0x1) | // Divide by 1 for 44MHz from FPGA clock in clockr pin
MCBSP_SRGR1_FWID(0x1); // Frame Width. This value + 1 determines the width of the frame-sync pulse, FSG, during its active period.
mcBspRegs->RCR2 &= ~MCBSP_PHASE_SINGLE; // Choose single phase for the Receive Frame
mcBspRegs->RCR1 |= MCBSP_WORD_LENGTH_20; // Receive Word Length = 20-bit
mcBspRegs->RCR1 |= MCBSP_FRAME_LENGTH(0x2); // Receive Frame Length = 40 (2 * 20-bit words)
mcBspRegs->XCR2 &= ~MCBSP_PHASE_SINGLE; // Choose single phase for the Transmit Frame
mcBspRegs->XCR1 |= MCBSP_WORD_LENGTH_20; // Transmit Word Length = 20-bit
mcBspRegs->XCR1 |= MCBSP_FRAME_LENGTH(0x2); // Transmit Frame Length = 40 (2 * 20-bit words)
mcBspRegs->XCCR &= ~0x8;
// Wait at least 2 SRG clock cycles
Delay();
// Enable the sample rate generator
mcBspRegs->SPCR2 |= MCBSP_SPCR2_GRST_RSTCLR;
// Wait at least 2 SRG clock cycles
Delay();
// Take the McBSP module out of Reset
mcBspRegs->SPCR1 |= MCBSP_SPCR1_RRST_RSTCLR;
mcBspRegs->SPCR2 |= MCBSP_SPCR2_FRST_RSTCLR | MCBSP_SPCR2_XRST_RSTCLR;
EnableInt(m_Port);
mcBspRegs->THRSH2 |= 0x7; // 2 word tx threshold (40 bits)
mcBspRegs->THRSH1 |= 0x1; // 2 word rx threshold (40 bits)
}
void McBspDriver::WriteFrame(McBspFrame frame)
{
Uint32 mcBspBaseAddr = PortToMcBspBaseAddress(m_Port);
OMAP_MCBSP_REGS* mcBspRegs = (OMAP_MCBSP_REGS*) mcBspBaseAddr;
if(mcBspRegs->SPCR2 & MCBSP_SPCR2_XRDY) // DXR register ready for a full frame
{
mcBspRegs->DXR = frame.word1; // Writes to the Data Transmit Register
mcBspRegs->DXR = frame.word2;
}
else
{
m_txFramesLost++;
printf("McBSP FIFO full on write");
FullError(LOC);
}
}
Please let me know if you find any issue in the code. Thanks