This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Long Wan,
SW request type with AUTO_INIT OFF mode will do only ONE FRAME as you found out.
Make sure that your HW request line is the correct request line and the source peripheral is configured properly to trigger DMA request.
Note that the request line and DMA channels are not the same thing (looking at Ch7 and request line 7 that you have).
Request Line 7 can be triggered by MIBADC1 / MIBSPI5 modules. Please refer to Section 6.16.2 Default DMA Request Map for the DMA request line connection in the data sheet page 95: www.ti.com/.../tms570ls3137.pdf
Joe
Hi Joe,
The purpose of my RAM to RAM test is try to implement SPI-DMA application in the project of UTC Aerospace Systems. According to Section 6.16.2 DMA request Map, I have set up request line 0 to DMA channel 7, and some SPI settings and made DMA from RAM to SPI Tx Register through hardware DMA_REQ working properly!!! Thank you for your help!
However, there are some problems in SPI side now. When the following function get called the SPI is sending continuously and going forever. The data is DMAed data through hardware DMA_REQ. If I commented out the following line for spiREG1->TGCTRL[1] setting in the function,
| (TRG_ALWAYS << 20) // trigger event, if this line is commented out, there will be no SPI clock, no DMA request sent!
then SPI will not send out any thing at all. My question is how can make SPI send the data out exactly. As seen by using LARGE_COUNT , I put
spiREG1->DMACOUNT[CHANNEL_NO] = ( numBytes << 16 );
and hardware DMA_REQ just made exactly the number of requests as the data size for 16-bit data transfer. That is quite good. I know that TRG_ALWAYS may cause the sending forever problem. But should remove this line, it will not trigger the SPI clock event, though the following two line that enables SPI machine.
spiREG1->DMAREQEN = 1; // condition 1 to start for normal SPI DMA, not for multi-buffer ram
spiREG1->ENA = 1U; // SPIENA condition 2 to start for normal SPI DMA, not for multi-buffer ram
Please help me on SPI side for SPI-DMA application.
Thank you and Best Regards,
Long Wan
//==============================================================================
#define CHANNEL_NO 7
#define LINE_NO 0
#define LARGE_COUNT //LARGE_COUNT looks required for the following set-up. Otherwise, the scope got meaningless curve
void SS_NVM_SPI_DMA_WriteBlockTest(SS_U16 *dataBlock, SS_U32 startAddress, SS_U32 numBytes)
{
SS_DMA_CONTROL_PACKET_ST dmaCtrlPktn;
dmaREG->GCTRL = 0x00000001U; /* reset dma */
while(dmaREG->GCTRL);
dmaCtrlPktn.SADD = (SS_U32)(dataBlock); //source address of DMA, Post-incremented
dmaCtrlPktn.DADD = 0xff0e0006; //0xff0e0006; destination of SPI-DMA, Fixed address needed here
// this is buffer 1 address is verified by scope
dmaCtrlPktn.FRCNT = (numBytes); //Frame count
dmaCtrlPktn.ELCNT = 1; //element count
dmaCtrlPktn.PORTASGN = 4U; //Port B
dmaCtrlPktn.ADDMODERD = ADDR_INC1; //post-incremented
// dmaCtrlPktn.ADDMODEWR = ADDR_INC1; //ADDR_FIXED is required for SPI-DMA, here just for testing to see whether or not a block of data is
dmaCtrlPktn.ADDMODEWR = ADDR_FIXED; //ADDR_FIXED; //constant
dmaCtrlPktn.RDSIZE = SS_DMA_ACCESS_16_BIT; //16-bit
dmaCtrlPktn.WRSIZE = SS_DMA_ACCESS_16_BIT; //16-bit
dmaCtrlPktn.TTYPE = FRAME_TRANSFER; //FRAME_TRANSFER is required for SPI-DMA
dmaCtrlPktn.AUTOINIT = AUTOINIT_ON; //AUTOINIT_OFF AUTOINIT_ON auto-init
dmaCtrlPktn.CHCTRL = 0; //CHANNEL_NO +1; // 0 for not chaining. n+1 for channel n, channel control, chain channel
dmaCtrlPktn.ELDOFFSET = 0; //element destination offset
dmaCtrlPktn.ELSOFFSET = 0; //element source offset
dmaCtrlPktn.FRDOFFSET = 0; //frame destination offset
dmaCtrlPktn.FRSOFFSET = 0; //frame source offset
SS_DMA_ReqAssign(CHANNEL_NO, LINE_NO); // (SS_U32 channel, SS_U32 reqline)
SS_DMA_SetCtrlPacket(CHANNEL_NO, &dmaCtrlPktn);
SS_DMA_SetChEnable(CHANNEL_NO, SS_DMA_REQ_TYPE_HW); // SS_DMA_REQ_TYPE_HW is required for SPI-DMA
dmaREG->GCTRL |= 0x00010000U; /* enable dma */
spiREG1->ENA = 0; // SPIENA hold low for configuration
spiREG1->GCR0 = 1; // to allow SPI register configurable per 14.8 on page 617
/** enable SPI multi-buffered mode and enable buffer RAM */
while (spiREG1->BUFINIT) ; // wait until this bit is cleared
spiREG1->PCFUN |= (1 /* SCS[0] */
| (1 << 1)
| (1 << 9) /* CLK */
| (1 << 10) /* SIMO */
| (1 << 11)); /* SOMI */
// spiREG1->GCR1 = ... // CLKMOD, MASTER bit setting
spiREG1->GCR1 = (1 << 1) /* CLOCKMOD */
| 1; /* MASTER */
// spiREG1->FMT[0] = ... // set wait, delay, phase, shift direction ...
// spiREG1->DELAY = ... // set as Master delay values
spiREG1->DELAY = (5 << 24) /* C2TDELAY */
| (0 << 16) /* T2CDELAY */
| (0 << 8) /* T2EDELAY */
| 0; /* C2EDELAY */
spiREG1->FMT0 = 0; // already cleared to 0, the following 3 lines are not necessary needed.
// spiREG1->FMT0 &= ~(1 << 24); // wdelay
// spiREG1->FMT0 &= ~(1 << 20); // shift direction
// spiREG1->FMT0 &= ~(1 << 17); // clock polarity
spiREG1->FMT0 |= (1 << 16); /* clock phase */
spiREG1->FMT0 |= (baudratePrescaler << 8); /* baudrate prescale */
spiREG1->FMT0 |= 16; /* data word length */
while(spiREG1->BUFINIT & 0x1000000); // wait until BUFINITACTIVE = 0
/** - initialize transfer groups */
spiREG1->TGCTRL[1] = (1 << 31) // TGENA
| (0 << 29) // pcurrent reset
| (TRG_ALWAYS << 20) // trigger event, if this line is commented out, there will be no SPI clock, no DMA request sent!
| (TRG_DISABLED << 16) // trigger source
| (1 << 8); // start buffer
/* The following TGs are unused */
spiREG1->TGCTRL[2] = (2 << 8); /* start buffer */
spiREG1->TGCTRL[3] = (2 << 8); /* start buffer */
spiREG1->TGCTRL[4] = (2 << 8); /* start buffer */
spiREG1->TGCTRL[5] = (2 << 8); /* start buffer */
spiREG1->TGCTRL[6] = (2 << 8); /* start buffer */
spiREG1->TGCTRL[7] = (2 << 8); /* start buffer */
spiREG1->TGCTRL[8] = (2 << 8);
spiREG1->LTGPEND = 1; // TG end pointer
// TG 1
spiRAM1->tx[1].control = (4 << 13); // buffer mode Continues mode
spiRAM1->tx[1].control |= (1 << 12); // hold chip select
spiRAM1->tx[1].control &= ~(1 << 11); // lock transmission
spiRAM1->tx[1].control &= ~(1 << 8); // data format
spiRAM1->tx[1].control |= CS_0; // chip select
// spiREG1->DMACNTLEN = 1U; // select large count for SPI DMA, here try small first
/** - set interrupt levels */
spiREG1->LVL = 0;
/** - clear any pending interrupts */
spiREG1->FLG = 0xFFFFFFFFU;
/** - enable/disable interrupts */
spiREG1->INT0 = 0;
/** @b initialize @b SPI @b Port */
/** - SPI Port output values */
/* Set CS high */
spiREG1->PCDOUT |= 1; /* SCS[0] */
spiREG1->PCDOUT &= ~((1 << 9) /* CLK */
| (1 << 10) /* SIMO */
| (1 << 11)); /* SOMI */
/** - SPI Port direction - outputs */
spiREG1->PCDIR |= 1 /* SCS[0] */
| (1 << 9) /* CLK */
| (1 << 10); /* SIMO */
/** - SPI Port direction - inputs */
spiREG1->PCDIR &= ~(1 << 11); /* SOMI */
/** - SPI Port open drain enable */
spiREG1->PCPDR &= ~( 1 /* SCS[0] */
| (1 << 9) /* CLK */
| (1 << 10) /* SIMO */
| (1 << 11)); /* SOMI */
/** - SPI Port pullup / pulldown selection */
spiREG1->PCPSL |= 1 /* SCS[0] */
| (1 << 9) /* CLK */
| (1 << 10) /* SIMO */
| (1 << 11); /* SOMI */
/** - SPI Port pullup / pulldown enable*/
spiREG1->PCDIS &= ~( 1 /* SCS[0] */
| (1 << 9) /* CLK */
| (1 << 10) /* SIMO */
| (1 << 11)); /* SOMI */
/* SPI set all pins to functional */
spiREG1->PCFUN |= (1 /* SCS[0] */
| (1 << 9) /* CLK */
| (1 << 10) /* SIMO */
| (1 << 11)); /* SOMI */
// spiREG1->DMACNTLEN = 0x01; // Enable large count
/** - start SPI */
spiREG1->CSDEF = 1U; //
#ifdef LARGE_COUNT
spiREG1->DMACNTLEN = 1U; // select large count for SPI DMA
spiREG1->RAMACCESS = 0; // not to use Multi-buffer mode by set bit MSPIENA
#else
spiREG1->RAMACCESS |= 1U; // to use Multi-buffer mode by set bit MSPIENA
#endif
dmaREG->DREQASI[1] = LINE_NO; // channel 7 (bit 0-5 of DREQASI[1])is assigned for line 0 to trigger DMA
spiREG1->DMACTRL[CHANNEL_NO].ONESHOT = 1; // set, not clear ONESHOT
spiREG1->DMACTRL[CHANNEL_NO].NOBRK = 1U; // set NOBRK
spiREG1->DMACTRL[CHANNEL_NO].BUFID = 1; // a 7-bit BUFID. Start from No. 0 buffer RAM: 0 ~ 127, total 128 buffer RAMs. My set-up is using buffer1 that is verified by scope
spiREG1->DMACTRL[CHANNEL_NO].TXDMA_MAP = LINE_NO; // DMA TX channel line number?
spiREG1->DMACTRL[CHANNEL_NO].RXDMA_MAP = LINE_NO+1; // DMA RX channel line number? RXDMA_MAP should be different from TXDMA_MAP, see page 698 of data sheet
spiREG1->DMACTRL[CHANNEL_NO].ICOUNT = numBytes; // send by ICOUNT+1 buffer, confusing? 5-bit count can send max buffer with 32. However there are 128 16-bit in single Tx buffer.
spiREG1->DMACTRL[CHANNEL_NO].COUNT = numBytes+1; // send by ICOUNT+1 buffer,
#ifdef LARGE_COUNT
spiREG1->DMACOUNT[CHANNEL_NO] = ( numBytes << 16 );
#endif
spiREG1->DMACTRL[CHANNEL_NO].TXDMA_ENA = 1U;
spiREG1->DMACTRL[CHANNEL_NO].RXDMA_ENA = 1U;
/////////////////////////////////////////////////// ther following 2 items have been tested and there is no effect on scope result
spiREG1->TGCTRL[CHANNEL_NO] &= 0xffff00ff; // let PSTART = 0;
spiREG1->TGCTRL[CHANNEL_NO] |= 0x80000000; // set TGENA bit
////////////////////////////////////////////////////////////////////////
spiREG1->DMAREQEN = 1; // condition 1 to start for normal SPI DMA, not for multi-buffer ram
spiREG1->ENA = 1U; // SPIENA condition 2 to start for normal SPI DMA, not for multi-buffer ram
}