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.
