Tool/software: Code Composer Studio
Hi all,
because I´m emulating an I2S-interface described in document spma042b.pdf I want two use two SSI-modules (SSI0 and SSI3) with µDMA in Ping-Pong-Mode. SSI0 ist the left and SSI3 ist the right channel. But SSI0 only is transferring data and SSI3 don´t get into the interrupt. Have you some tipps for me?
// Buffer definitions outside main.c
#pragma DATA_SECTION(inbuffera1, ".data")
static uint16_t inbuffera1[BUFF_SIZE];
#pragma DATA_SECTION(inbuffera2, ".data")
static uint16_t inbuffera2[BUFF_SIZE];
#pragma DATA_SECTION(outbuffera1, ".data")
static uint16_t outbuffera1[BUFF_SIZE];
#pragma DATA_SECTION(outbuffera2, ".data")
static uint16_t outbuffera2[BUFF_SIZE];
#pragma DATA_SECTION(inbufferb1, ".data")
static uint16_t inbufferb1[BUFF_SIZE];
#pragma DATA_SECTION(inbufferb2, ".data")
static uint16_t inbufferb2[BUFF_SIZE];
#pragma DATA_SECTION(outbufferb1, ".data")
static uint16_t outbufferb1[BUFF_SIZE];
#pragma DATA_SECTION(outbufferb2, ".data")
static uint16_t outbufferb2[BUFF_SIZE];
// uDMA control table aligned to 1024-byte boundary outside main.c
#pragma DATA_ALIGN(ucControlTable, 1024)
uint16_t ucControlTable[1024];
// Functions called inside main.c
void hwi_SSI0_ISR(void)
{
uint32_t ui32Status;
uint32_t ui32Mode;
ui32Status = SSIIntStatus(SSI0_BASE, 1);
SSIIntClear(SSI0_BASE, ui32Status);
ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
//wssus(inbuffera1, outbuffera1);
g_ui32SSIRxPingCount++;
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,(void *)(SSI0_BASE + SSI_O_DR), inbuffera1, sizeof(inbuffera1));
}
ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_ALT_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
//wssus(inbuffera2, outbuffera2);
g_ui32SSIRxPongCount++;
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI0_BASE + SSI_O_DR), inbuffera2, sizeof(inbuffera2));
}
ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32SSITxPingCount++;
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, outbuffera1, (void *)(SSI0_BASE + SSI_O_DR), sizeof(outbuffera1));
}
ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_SSI0TX | UDMA_ALT_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32SSITxPongCount++;
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, outbuffera2, (void *)(SSI0_BASE + SSI_O_DR), sizeof(outbuffera2));
}
}
void hwi_SSI3_ISR(void)
{
uint32_t ui32Status;
uint32_t ui32Mode;
ui32Status = SSIIntStatus(SSI3_BASE, 1);
SSIIntClear(SSI3_BASE, ui32Status);
ui32Mode = uDMAChannelModeGet(UDMA_CH14_SSI3RX | UDMA_PRI_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
//wssus(inbufferb1, outbufferb1);
g_ui32SSIRxPingCount++;
uDMAChannelTransferSet(UDMA_CH14_SSI3RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,(void *)(SSI3_BASE + SSI_O_DR), inbufferb1, sizeof(inbufferb1));
}
ui32Mode = uDMAChannelModeGet(UDMA_CH14_SSI3RX | UDMA_ALT_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
//wssus(inbufferb2, outbufferb2);
g_ui32SSIRxPongCount++;
uDMAChannelTransferSet(UDMA_CH14_SSI3RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI3_BASE + SSI_O_DR), inbufferb2, sizeof(inbufferb2));
}
ui32Mode = uDMAChannelModeGet(UDMA_CH15_SSI3TX | UDMA_PRI_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32SSITxPingCount++;
uDMAChannelTransferSet(UDMA_CH15_SSI3TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, outbufferb1, (void *)(SSI3_BASE + SSI_O_DR), sizeof(outbufferb1));
}
ui32Mode = uDMAChannelModeGet(UDMA_CH15_SSI3TX | UDMA_ALT_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32SSITxPongCount++;
uDMAChannelTransferSet(UDMA_CH15_SSI3TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, outbufferb2, (void *)(SSI3_BASE + SSI_O_DR), sizeof(outbufferb2));
}
}
// Initialize SSI uDMA transfer
void Init_SSI0_uDMA_Transfer(void)
{
// Enable uDMA
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)); // wait until uDMA is ready
IntEnable(INT_UDMAERR);
uDMAEnable();
uDMAControlBaseSet(ucControlTable);
SSIDMAEnable(SSI0_BASE, SSI_DMA_RX | SSI_DMA_TX); // Enable TX and RX channels.
//HWREG(SSI0_BASE + SSI_O_CR1) |= SSI_CR1_LBM; // Loopback-mode (data sent to TX (output) to RX (input) )
uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI0RX, UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)); // assure starting point for RX-channel
//****************************************************************************
//uDMA SSI0 RX Ping
//****************************************************************************
uDMAChannelControlSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_16); // transfer element size RX Ping
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI0_BASE + SSI_O_DR), inbuffera1, sizeof(inbuffera1)); // source and destination for RX Ping
//****************************************************************************
//uDMA SSI0 RX Pong
//****************************************************************************
uDMAChannelControlSet(UDMA_CHANNEL_SSI0RX | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_16); // transfer element size RX Pong
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI0_BASE + SSI_O_DR), inbuffera2, sizeof(inbuffera2)); // source and destination for RX Pong
uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI0TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); // put attributes in known state
uDMAChannelAttributeEnable(UDMA_CHANNEL_SSI0TX, UDMA_ATTR_USEBURST); // use burst mode (transfer, when 4 or more items are in RX FIFO)
//****************************************************************************
//uDMA SSI0 TX Ping
//****************************************************************************
uDMAChannelControlSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_16); // transfer element size
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, outbuffera1, (void *)(SSI0_BASE + SSI_O_DR), sizeof(outbuffera1));
//****************************************************************************
//uDMA SSI0 TX Pong
//****************************************************************************
uDMAChannelControlSet(UDMA_CHANNEL_SSI0TX | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_16);
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, outbuffera2, (void *)(SSI0_BASE + SSI_O_DR), sizeof(outbuffera2));
uDMAChannelEnable(UDMA_CHANNEL_SSI0RX);
uDMAChannelEnable(UDMA_CHANNEL_SSI0TX);
SSIIntEnable(SSI0_BASE, SSI_DMATX | SSI_DMARX); // Enable the SSI0 DMA TX/RX interrupts.
IntEnable(INT_SSI0); // Enable the SSI0 peripheral interrupts.
}
void Init_SSI3_uDMA_Transfer(void)
{
//uDMAChannelSelectSecondary();
SSIDMAEnable(SSI3_BASE, SSI_DMA_RX | SSI_DMA_TX); // Enable TX and RX channels.
uDMAChannelAttributeDisable(UDMA_CH14_SSI3RX, UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)); // assure starting point for RX-channel
//****************************************************************************
//uDMA SSI3 RX Ping
//****************************************************************************
uDMAChannelControlSet(UDMA_CH14_SSI3RX | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_16); // transfer element size RX Ping
uDMAChannelTransferSet(UDMA_CH14_SSI3RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI3_BASE + SSI_O_DR), inbufferb1, sizeof(inbufferb1)); // source and destination for RX Ping
//****************************************************************************
//uDMA SSI3 RX Pong
//****************************************************************************
uDMAChannelControlSet(UDMA_CH14_SSI3RX | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_16); // transfer element size RX Pong
uDMAChannelTransferSet(UDMA_CH14_SSI3RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI3_BASE + SSI_O_DR), inbufferb2, sizeof(inbufferb2)); // source and destination for RX Pong
uDMAChannelAttributeDisable(UDMA_CH15_SSI3TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); // put attributes in known state
uDMAChannelAttributeEnable(UDMA_CH15_SSI3TX, UDMA_ATTR_USEBURST); // use burst mode (transfer, when 4 or more items are in RX FIFO)
//****************************************************************************
//uDMA SSI3 TX Ping
//****************************************************************************
uDMAChannelControlSet(UDMA_CH15_SSI3TX | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_16); // transfer element size
uDMAChannelTransferSet(UDMA_CH15_SSI3TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, outbufferb1, (void *)(SSI3_BASE + SSI_O_DR), sizeof(outbufferb1));
//****************************************************************************
//uDMA SSI3 TX Pong
//****************************************************************************
uDMAChannelControlSet(UDMA_CH15_SSI3TX | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_16);
uDMAChannelTransferSet(UDMA_CH15_SSI3TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, outbufferb2, (void *)(SSI3_BASE + SSI_O_DR), sizeof(outbufferb2));
uDMAChannelEnable(UDMA_CH14_SSI3RX);
uDMAChannelEnable(UDMA_CH15_SSI3TX);
SSIIntEnable(SSI3_BASE, SSI_DMATX | SSI_DMARX); // Enable the SSI3 DMA TX/RX interrupts.
IntEnable(INT_SSI3); // Enable the SSI0 peripheral interrupts.
}
void Init_SSI(void)
{
// GPIO setup for SSI0
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_SSI0);
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA4_SSI0RX);
GPIOPinConfigure(GPIO_PA5_SSI0TX);
GPIOPinTypeSSI(GPIO_PORTA_BASE,GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_2);
SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE, 10000, 16);
SSIEnable(SSI0_BASE);
// GPIO setup for SSI3
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_SSI3);
GPIOPinConfigure(GPIO_PD0_SSI3CLK);
GPIOPinConfigure(GPIO_PD1_SSI3FSS);
GPIOPinConfigure(GPIO_PD2_SSI3RX);
GPIOPinConfigure(GPIO_PD3_SSI3TX);
GPIOPinTypeSSI(GPIO_PORTD_BASE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
SSIConfigSetExpClk(SSI3_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE, 10000, 16);
SSIEnable(SSI3_BASE);
}
// called inside main.c
FPULazyStackingEnable();
//Set CPU Clock to 80MHz. 400MHz PLL/2 = 200 DIV 2.5 = 80MHz
SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
SysCtlPeripheralClockGating(true);
Init_AIC3104();
Init_SSI();
Init_SSI0_uDMA_Transfer();
Init_SSI3_uDMA_Transfer();
BIOS_start();