Hello!
In my design I need to read data from ADS8900 at 500kSPS to Tiva MCU.
I want to do it without interrupts, with uDMA, as during aquisition MCU should process data.
The task is: each time I generate a CONVST pulse I neet to start aquiring next sample, 4100 samples total, and then trigger data processing.
So I need my timer to trigger 3-byte SSI transfer via uDMA, and use another channel to transfer 4100 * 3 bytes triggered by SSI.
First of all, I see a bug in uDMAChannelEnable routine - it cleares other channel enables, as it looks like
HWREG(UDMA_ENASET) = 1 << ui8ChannelNum;
But next I do not see any transfers to SSI. Here is my code:
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1); GPIOPinConfigure(GPIO_PE4_SSI1XDAT0); GPIOPinConfigure(GPIO_PE5_SSI1XDAT1); GPIOPinConfigure(GPIO_PB5_SSI1CLK); GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_5); GPIOPinTypeSSI(GPIO_PORTE_BASE, GPIO_PIN_4); GPIOPinTypeSSI(GPIO_PORTE_BASE, GPIO_PIN_5); SSIConfigSetExpClk(SSI1_BASE, g_ui32SysClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 22000000, 8); SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_READ_WRITE); SSIAdvFrameHoldEnable(SSI1_BASE); SSIEnable(SSI1_BASE); SSIDMAEnable(SSI1_BASE, SSI_DMA_RX); uDMAEnable(); uDMAControlBaseSet(pui8ControlTable); uDMAChannelAssign(UDMA_CH10_SSI1RX); uDMAChannelAssign(UDMA_CH0_TIMER4A); #define UDMA_CHANNEL_TMR4A UDMA_CHANNEL_USBEP1RX uDMAChannelAttributeDisable(UDMA_CHANNEL_TMR4A, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); uDMAChannelControlSet(UDMA_CHANNEL_TMR4A | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_1); uDMAChannelTransferSet(UDMA_CHANNEL_TMR4A | UDMA_PRI_SELECT, UDMA_MODE_AUTO, (void *)ADCReq, (void *)(SSI1_BASE + SSI_O_DR), 3); uDMAChannelAttributeEnable(UDMA_CHANNEL_TMR4A, UDMA_ATTR_USEBURST); uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI1RX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); uDMAChannelControlSet(UDMA_CHANNEL_SSI1RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1); uDMAChannelTransferSet(UDMA_CHANNEL_SSI1RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI1_BASE + SSI_O_DR), (void *)ADCData1, 4100 * 3); uDMAChannelControlSet(UDMA_CHANNEL_SSI1RX | UDMA_ALT_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1); uDMAChannelTransferSet(UDMA_CHANNEL_SSI1RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI1_BASE + SSI_O_DR), (void *)ADCData2, 4100 * 3); HWREG(UDMA_ENASET) = (1 << UDMA_CHANNEL_TMR4A) + (1 << UDMA_CHANNEL_SSI1RX); GPIOPinTypeTimer(GPIO_PORTL_BASE, GPIO_PIN_4 | GPIO_PIN_5); GPIOPinConfigure(GPIO_PL4_T0CCP0); GPIOPinConfigure(GPIO_PL5_T0CCP1); TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM); TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock / 500000); TimerMatchSet(TIMER0_BASE, TIMER_A, TimerLoadGet(TIMER0_BASE, TIMER_A) - 10); //TimerDMAEventSet(TIMER0_BASE, TIMER_DMA_TIMEOUT_A); TimerLoadSet(TIMER0_BASE, TIMER_B, g_ui32SysClock / 500000); TimerMatchSet(TIMER0_BASE, TIMER_B, 100); TimerControlLevel(TIMER0_BASE, TIMER_B, true); TimerEnable(TIMER0_BASE, TIMER_BOTH); SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER4); TimerConfigure(TIMER4_BASE, TIMER_CFG_PERIODIC); TimerLoadSet(TIMER4_BASE, TIMER_A, g_ui32SysClock / 500000); TimerDMAEventSet(TIMER4_BASE, TIMER_DMA_TIMEOUT_A); TimerEnable(TIMER4_BASE, TIMER_A);
Timer 0A is used for CONVST generation, Timer 0B - for CS generation, and Timer 4 should trigger uDMA transfers to SSI, but it does not.
What is wrong?