Other Parts Discussed in Thread: OMAP3530
Hi,
I using OMAP 3530 on Mistral Board and I'm having problems in run eDMA correct on Linux kernel.
- The problem is that I only receive the data on the first time the eDMA works. The following times my buffer isn't updated, staying with same data transfer at the first time.
To simulate the eDMA working I made the McBSP1 port send 16 data size of short and McBSP3 port to receive the data. The problema is that when I am using the eDMA only the first time I send the data is buffered in the vector. The next time I send any data the buffer isn't updated. The main loop I make the port configurations and the eDMA configuration every time.
When I using the port without eDMA I can see all the data in the internal port buffer. So the port configurations is working properly, receiving data. The code below is the code I am using to simulate and use the eDMA for reception.
int main_loop ()
{
while (1)
{
clear_receiver_buffer ();
configure_mcbsp1 ();
configure_mcbsp3 ();
send_data();
configure_dma ();
check_buffer ();
}
}
// Configure McBSP1 To Transmit
configure_mcbsp1 ()
{
BASE = 0x48074000;
// Initialize McBSP1 Registers
*(BASE + McBSP_SPCR2) = 0x00000000;
*(BASE + McBSP_SPCR1) = 0x00000000;
// Set Run Free Mode For TX And RX And Set Generation Of Interrupts
*(BASE + McBSP_SPCR2) = 0x00000230;
*(BASE + McBSP_SPCR1) = 0x00000020;
// Set Receive Word Length To 16 Bits And 1 Bit Data Delay
*(BASE + McBSP_RCR1) = 0x00000040;
*(BASE + McBSP_RCR2) = 0x00000001;
// Set Transmitter Word Length To 16 Bits And 1 Bit Data Delay
*(BASE + McBSP_XCR1) = 0x00000040;
*(BASE + McBSP_XCR2) = 0x00000001;
// Set Frame Sync Mode For TX And RX And Clock Polarity
*(BASE + McBSP_PCR) = 0x00000B00;
// Set Frame Sync Width And Divide Clock By 1
*(BASE + McBSP_SRGR1) = 0x00000000;
// Setup Clock Settings And Frame Period (Time Between Frame Syncs)
*(BASE + McBSP_SRGR2) = 0x00000040;
// All Channels Enable But Masked
*(BASE + McBSP_MCR2) = 0x00000002;
*(BASE + McBSP_MCR1) = 0x00000001;
// Enable Channel 0 To Transmit
*(BASE + McBSP_XCERA) = 0x00000001;
// Enable Channel 0 To Receive
*(BASE + McBSP_RCERA) = 0x00000001;
// Set Threshold To 0
*(BASE + McBSP_THRSH2) = 0x00000000;
// Clear All Interrupts
*(BASE + McBSP_IRQSTATUS) = 0x00007FBF;
// Enable Receive
*(BASE + McBSP_SPCR1) |= 0x00000001;
// Enables Sample Rate Generator
*(BASE + McBSP_SPCR2) |= 0x00000040;
// Enables Frame Sync Logic
//*(BASE + McBSP_SPCR2) = *(BASE + McBSP_SPCR2) | 0x00000080;
// Enables Transmitter
//*(BASE + McBSP_SPCR2) = *(BASE + McBSP_SPCR2) | 0x00000001;
}
configure_mcbsp3 ()
{
BASE = 0x49024000;
// Initialize McBSP1 Registers
*(BASE + McBSP_SPCR2) = 0x00000000;
*(BASE + McBSP_SPCR1) = 0x00000000;
// Set Run Free Mode For RX And Set Generation Of Interrupts
*(BASE + McBSP_SPCR1) = 0x00000020;
// Set Receive Word Length To 16 Bits And 1 Bit Data Delay
*(BASE + McBSP_RCR1) = 0x00000040;
*(BASE + McBSP_RCR2) = 0x00000001;
// Set Frame Sync Mode For RX And Clock Polarity
*(BASE + McBSP_PCR) = 0x00000000;
// Set Frame Sync Width And Divide Clock By 1
*(BASE + McBSP_SRGR1) = 0x00000000;
// Setup Clock Settings And Frame Period (Time Between Frame Syncs)
*(BASE + McBSP_SRGR2) = 0x00000040;
// All Channels Enable But Masked
*(BASE + McBSP_MCR2) = 0x00000002;
*(BASE + McBSP_MCR1) = 0x00000001;
// Enable Channel 0 To Receive
*(BASE + McBSP_RCERA) = 0x00000001;
// Set Threshold To Receive 93 Data
*(BASE + McBSP_THRSH1) = 0x0000005C;
// Clear All Interrupts
*(BASE + McBSP_IRQSTATUS) = 0x00007FBF;
// Enable Receive Interrupt
*(BASE + McBSP_IRQENABLE) = 0x00000008;
// Enable Receive
*(BASE + McBSP_SPCR1) |= 0x00000001;
// Enables Sample Rate Generator
*(BASE + McBSP_SPCR2) |= 0x00000040;
}
{
// Enable True Interrupt
SYSC_LICFG0 = SYSC_LICFG0 | 0x00000100;
// Select Interrupt which will trigger eDMA
uiDMAChannel = 5;
// Words amount to receiver
usSize = 16;
// Clear All Pending Interrupts From TPCC Module
*( TPCC_ICR) = 0xFFFFFFFF;
// Clear DMA Mask Bit To Work
*( WUGEN_MEVTCLR2) |= 0x00000001 << uiDMAChannel;
// Active Complete Interrupt
*( TPCC_OPT ) = 0x00100000;
// Set Interrupt To uiDMAChannel Value
*( TPCC_OPT ) |= uiDMAChannel << 12;
// Destination Start Address
*(TPCC_DST) = (unsigned int) Receiver_Buffer;
// Source Start Address (McBSP1_DRR)
*( TPCC_SRC) = (unsigned int) BASE;
// Set 8 TS To Transmit
*(TPCC_CCNT) = 0x00000001;
// Set 16 Elements (16 Word/TS) (ACNT = 4 BCNT = 16)
*(TPCC_ABCNT) = 0x00000004;
*(TPCC_ABCNT) |= (usSize << 16);
// Set Offset To Vector
*(PCC_BIDX) = 0x00040000;
// Set Offset To Next TS
*( TPCC_CIDX) = 0x00000000;
// Enable Link
*(TPCC_LNK) = 0x0000FFFF;
// Set DMA Channel uiDMAChannel To Use PaRAM uiDMAChannel
*( TPCC_DCHMAP ) = 0x00000000;
*( TPCC_DCHMAP ) = uiDMAChannel << 5;
// Enable Event To DMA Interrupt (EER Register)
*(TPCC_EESR) = 0x00000001 << uiDMAChannel;
// Enable DMA Channel Interrupt
*(TPCC_IESR) = 0x00000001 << uiDMAChannel;
}
I can see the data send with a oscilloscope. Soh I know that my data is send correct.
When active the eDMA interrupt (TPCC_GLOBAL_INTERRUPT - Evt 29) I see (with a GPIO) that every 16 data transfer the GPIO is set.
Soh the eDMA is identifying the frame sync. But the data isn't updated in the reception buffer.
I simulate the same code in CCS4 with emulator XDS510 and the code work correct. Ever time I send 16 data I receive 16 data in my reception buffer.
I don't have any idea to make eDMA work in Linux kernel. In my code I am using DSP Link library I don't know if it is influencing.
Anyone know what is going on ?
Thanks a lot.
