Hello TI community. I'm developing on the Tiva C for my senior design project and am currently having some issues transmitting multiple bytes of data over SPI through the DMA controller.
My end goal is to send 3 bytes of data to an external DAC that is controlled by 24 bit messages. I've red over the various tutorials and examples, but have had no luck viewing the SPI transmit data on a logic analyzer when the dma request is asserted.
Below is my code I am using for testing features (sorry for the mess, still early on in the development cycle), any help would be much appreciated!!!
//*****************************************************************************
//
// Testing the peripherals and stuff.
//
//*****************************************************************************
// c includes
#include <stdint.h>
#include <stdbool.h>
// part include
#include "inc/tm4c123gh6pm.h"
// hardware includes
#include "inc/hw_memmap.h"
#include "inc/hw_ssi.h"
#include "inc/hw_types.h"
// driver library includes
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/udma.h"
// custom includes
#include "dac.h"
#include "dsp.h"
#pragma DATA_ALIGN(pui8ControlTable, 1024)
uint8_t pui8ControlTable[1024];
//*****************************************************************************
//
// Timer0 Interrupt
//
//*****************************************************************************
// TODO: CHANGE SETUP SUCH THAT DMA TRANSFERS ARE UTILIZED
uint8_t pui16SSITransmitBuffer[DAC_BYTE_SIZE] = {0xFF, 0x00, 0xFF};
uint8_t pui16SSIRecieveBuffer[DAC_BYTE_SIZE] = {0x00, 0x00, 0x00};
void Timer0IntHandler(void)
{
// clear the interrupt
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
/*
if (ui16Count++ >= 20)
{
ui16Out = ui16Out == 0x7FFF ? 0x7000 : 0x7FFF;
ui16Count = 0;
}
// send sample out
SSIDataPutNonBlocking(SSI0_BASE, ui16Out);
if (GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4);
}
*/
uDMAChannelRequest(UDMA_CHANNEL_SSI0TX);
//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0);
}
//*****************************************************************************
//
// Blink the on-board LED, interrupt style.
//
//*****************************************************************************
int
main(void)
{
uint32_t ui32Period;
// configure operating frequency
SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
// enable needed peripherals
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
// configure general purpose input and output
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3);
// configure ssi module
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
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_MASTER, 5000000, 16);
SSIDMAEnable(SSI0_BASE, SSI_DMA_TX);
SSIEnable(SSI0_BASE);
// configure udma
uDMAEnable();
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
uDMAControlBaseSet(pui8ControlTable);
uDMAChannelSelectDefault(UDMA_DEF_SSI0TX_SEC_SSI1TX | UDMA_DEF_SSI0RX_SEC_SSI1RX);
uDMAChannelControlSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT,
UDMA_MODE_AUTO,
pui16SSITransmitBuffer,
(void*) (SSI0_BASE + SSI_O_DR),
sizeof(pui16SSITransmitBuffer));
uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI0TX, UDMA_ATTR_ALTSELECT |UDMA_ATTR_HIGH_PRIORITY| UDMA_ATTR_REQMASK );
uDMAChannelAttributeEnable(UDMA_CHANNEL_SSI0TX, UDMA_ATTR_USEBURST);
uDMAChannelEnable(UDMA_CHANNEL_SSI0TX);
// configure timer module
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
ui32Period = SysCtlClockGet() / 44100;
TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period-1);
IntEnable(INT_TIMER0A);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
IntMasterEnable();
// start the timer module
TimerEnable(TIMER0_BASE, TIMER_A);
//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 8);
while(1)
{
// raise your dongers
}
}
P.S. Custom header files have little to nothing in them at all except for a few numeric defines, should be easy to spot and ignore.