I'm working with the LM4F230, trying to get uDMA ScatterGather mode working off a GPIO request. Currently I have the DMA working in basic mode off a GPIOA interrupt request that occurs every 20us. I would like to now implement scatterGather so that I don't have to set up the next transfer every 20us. Working off the udma_uart_sg.c example I've copied over the task list and scattergather initialization which has 6 tasks and then ends where the last 3 tasks put dummy data into the SSI tx buffer. Basically what I'd like to see at this point is the SPI clock run for those last 3 tasks. I've been unable to get this working. Any suggestions? Initialization code below.
Thanks
#pragma DATA_ALIGN(ucControlTable, 1024)
UINT8 ucControlTable[1024];
static unsigned char g_ucSrcBuf[1024];
static unsigned char g_ucSrcBuf1[300];
static unsigned char g_ucDstBuf1[123];
static unsigned char g_ucSrcBuf2[645];
static unsigned char g_ucDstBuf2[345];
static unsigned char g_ucSrcBuf3[79];
static unsigned char g_ucDstBuf3[556];
static unsigned char g_ucDstBuf[1024];
#define SRC_IDX_1 0
#define SRC_IDX_2 sizeof(g_ucSrcBuf1)
#define SRC_IDX_3 (SRC_IDX_2 + sizeof(g_ucSrcBuf2))
#define DST_IDX_1 0
#define DST_IDX_2 sizeof(g_ucDstBuf1)
#define DST_IDX_3 (DST_IDX_2 + sizeof(g_ucDstBuf2))
tDMAControlTable g_TaskTableSrc[] =
{
//
// Task 1: copy source buffer fragment 1
//
uDMATaskStructEntry(sizeof(g_ucSrcBuf1), UDMA_SIZE_8,
UDMA_SRC_INC_8, &g_ucSrcBuf[SRC_IDX_1],
UDMA_DST_INC_8, g_ucSrcBuf1,
UDMA_ARB_8, UDMA_MODE_PER_SCATTER_GATHER),
//
// Task 2: copy source buffer fragment 2
//
uDMATaskStructEntry(sizeof(g_ucSrcBuf2), UDMA_SIZE_8,
UDMA_SRC_INC_8, &g_ucSrcBuf[SRC_IDX_2],
UDMA_DST_INC_8, g_ucSrcBuf2,
UDMA_ARB_8, UDMA_MODE_PER_SCATTER_GATHER),
//
// Task 3: copy source buffer fragment 3
//
uDMATaskStructEntry(sizeof(g_ucSrcBuf3), UDMA_SIZE_8,
UDMA_SRC_INC_8, &g_ucSrcBuf[SRC_IDX_3],
UDMA_DST_INC_8, g_ucSrcBuf3,
UDMA_ARB_8, UDMA_MODE_PER_SCATTER_GATHER),
//
// Task 4: copy fragment buffer 1 to SSI
//
//
uDMATaskStructEntry(sizeof(g_ucSrcBuf1), UDMA_SIZE_8,
UDMA_SRC_INC_8, g_ucSrcBuf1,
UDMA_DST_INC_NONE, (void *)(SSI0_BASE + SSI_O_DR),
UDMA_ARB_8, UDMA_MODE_PER_SCATTER_GATHER),
//
// Task 5: copy fragment buffer 2 to SSI
//
//
uDMATaskStructEntry(sizeof(g_ucSrcBuf2), UDMA_SIZE_8,
UDMA_SRC_INC_8, g_ucSrcBuf2,
UDMA_DST_INC_NONE, (void *)(SSI0_BASE + SSI_O_DR),
UDMA_ARB_8, UDMA_MODE_PER_SCATTER_GATHER),
//
// Task 6: copy fragment buffer 3 to SSI
// mode is basic since this is last task
//
uDMATaskStructEntry(sizeof(g_ucSrcBuf3), UDMA_SIZE_8,
UDMA_SRC_INC_8, g_ucSrcBuf3,
UDMA_DST_INC_NONE, (void *)(SSI0_BASE + SSI_O_DR),
UDMA_ARB_8, UDMA_MODE_BASIC)
};
// initialize interrupt
ROM_GPIOIntTypeSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_FALLING_EDGE);
ROM_GPIOPinIntEnable(GPIO_PORTA_BASE, GPIO_PIN_3);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); // Enable uDMA controller at system level
ROM_uDMAEnable(); // Enable the uDMA controller
ROM_uDMAControlBaseSet(ucControlTable); // Point at the control table to use for channel control structures
ROM_uDMAChannelDisable(UDMA_CHANNEL_4); // Ensure channel is disabled before modifying register
ROM_uDMAChannelAssign(UDMA_CH4_GPIOA);
ROM_GPIODMATriggerEnable(GPIO_PORTA_BASE, GPIO_PIN_3);
ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_4,
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
ROM_uDMAChannelScatterGatherSet(UDMA_CHANNEL_4, 6, g_TaskTableSrc, TRUE);
ROM_uDMAChannelEnable(UDMA_CHANNEL_4);