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.

TM4C129 SSI PingPong uDMA TX done called endlessly

Other Parts Discussed in Thread: TM4C129ENCPDT

Hi,

I'm using a TM4C129ENCPDT to transfer data to a DAC using SSI Ping Pong mode.

Looking at different logs, the SSI seems to go through all the sequence properly (alternating between Ping and Pong transfers) except after the last transfer, the SSI interrupt handler keep triggering endlessly.


I checked several posts but did not find a viable answer.

I"m attaching a snipped code and SSI registers after the last block has been transferred and the SSI handler has triggered.

/**********************************************************************
**********************************************************************/
uint16_t gNumPacketsSent =  0;
uint16_t gNumPacketsMax  = 10;
uint16_t gStartAddress[10] = {ADD0, ADD1, ADD2, ADD3, ADD4, ADD5, ADD6, ADD7, ADD8, ADD9};

/**********************************************************************
**********************************************************************/
void SSI_Init(void)
{
	gNumPacketsSent = 0;

	//configure interface
	SSIDisable(				SSI0_BASE);
	SSIClockSourceSet(		SSI0_BASE,
							SSI_CLOCK_SYSTEM);
	SSIConfigSetClk(		ENDPOINT_SPI_DAC,
							gSysCtlClock,
							268.8e3 * 6,
							14);
	SSIEnable(				SSI0_BASE);
	IntEnable(				INT_SSI0);

	// Configure the DMA TX channel
	SSIDMADisable(SSI0_BASE,  	SSI_DMA_TX |
								SSI_DMA_RX);
	uDMAChannelAssign(			UDMA_CH11_SSI0TX);
	uDMAChannelAttributeDisable(UDMA_CH11_SSI0TX    | UDMA_PRI_SELECT,
								UDMA_ATTR_ALL);
	uDMAChannelAttributeDisable(UDMA_CH11_SSI0TX    | UDMA_ALT_SELECT,
								UDMA_ATTR_ALL);

	uDMAChannelAttributeEnable(	UDMA_CH11_SSI0TX    | UDMA_PRI_SELECT,
								UDMA_ATTR_USEBURST  |
								UDMA_ATTR_HIGH_PRIORITY);
	uDMAChannelAttributeEnable(	UDMA_CH11_SSI0TX    | UDMA_ALT_SELECT,
								UDMA_ATTR_USEBURST  |
								UDMA_ATTR_HIGH_PRIORITY);

	uDMAChannelControlSet(		UDMA_CH11_SSI0TX    | UDMA_PRI_SELECT,
								UDMA_SIZE_16        |
								UDMA_SRC_INC_16     |
								UDMA_DST_INC_NONE   |
								UDMA_ARB_4);
	uDMAChannelControlSet(		UDMA_CH11_SSI0TX    | UDMA_ALT_SELECT,
								UDMA_SIZE_16        |
								UDMA_SRC_INC_16     |
								UDMA_DST_INC_NONE   |
								UDMA_ARB_4);

	// Enable uDMA transmit complete interrupt
	SSIIntClear (SSI0_BASE, 	SSI_DMATX           |
								SSI_DMARX);
	SSIIntEnable(SSI0_BASE, 	SSI_DMATX);

}
/**********************************************************************
**********************************************************************/
void SSI0_Handler(void) {		// 8x16bit Tx/Rx FIFO

	uint32_t IntStatus;
	uint32_t uDMAModeTxPing;
	uint32_t uDMAModeTxPong;

	IntStatus = SSIIntStatus(SSI0_BASE, TRUE);
	SSIIntClear(SSI0_BASE, IntStatus);

	uDMAModeTxPing = uDMAChannelModeGet(UDMA_CH11_SSI0TX | UDMA_PRI_SELECT);
	uDMAModeTxPong = uDMAChannelModeGet(UDMA_CH11_SSI0TX | UDMA_ALT_SELECT);

	//setup a new transfer
	if(((uDMAModeTxPing == UDMA_MODE_STOP) && (uDMAModeTxPong != UDMA_MODE_STOP))||
	   ((uDMAModeTxPing != UDMA_MODE_STOP) && (uDMAModeTxPong == UDMA_MODE_STOP))) {

		SSIDacLoadManager();
	}
}
/**********************************************************************
**********************************************************************/
uint16_t SSIDacLoadManager() {

	//if its the last packet,
	//	we are done, shutdown
	if(gNumPacketsSent >= gNumPacketsMax) {
		SSIDMADisable(SSI0_BASE,SSI_DMA_TX |
								SSI_DMA_RX);
		SSIIntDisable(SSI0_BASE,SSI_TXEOT |
								SSI_DMATX |
								SSI_DMARX |
								SSI_TXFF  |
								SSI_RXFF  |
								SSI_RXTO  |
								SSI_RXOR);
	}

	//if its the first transfer
	//  load the primary structure
	//	start uDMA
	if(gNumPacketsSent == 0) {

		uDMAChannelTransferSet(	UDMA_CH11_SSI0TX | UDMA_PRI_SELECT,
								UDMA_MODE_PINGPONG,
								(void *)gStartAddress[gNumPacketsSent],
								(void *)(SSI0_BASE + SSI_O_DR),
								dataLength);

		uDMAChannelEnable(UDMA_CH11_SSI0TX);
		SSIDMAEnable(SSI0_BASE, SSI_DMA_TX);
	}//if its the first packet to send

	//if its a ping flag
	else if((gNumPacketsSent & 0x01) == 0x00 )

		uDMAChannelTransferSet(	UDMA_CH11_SSI0TX | UDMA_PRI_SELECT,
								UDMA_MODE_PINGPONG,
								(void *)gStartAddress[gNumPacketsSent],
								(void *)(SSI0_BASE + SSI_O_DR),
								dataLength);
	//if its a pong flag
	else if((gNumPacketsSent & 0x01) == 0x01 )

		uDMAChannelTransferSet(	UDMA_CH11_SSI0TX | UDMA_ALT_SELECT,
								UDMA_MODE_PINGPONG,
								(void *)gStartAddress[gNumPacketsSent],
								(void *)(SSI0_BASE + SSI_O_DR),
								dataLength);

	//send the next packet
	gNumPacketsSent++;
}

/**********************************************************************
**********************************************************************/
uint16_t main( ) {

	SSI_Init();
	SSIDacLoadManager();

}

Please help.

Khaled.