Part Number: TM4C129ENCPDT
Hi TI community,
I'm beginner with the interest in transfer array of 1024 bits of data continuously from tm4c129EXL board to 1.3" OLED display using DMA BASIC mode. Before that i tried below code.
Which transfer data from buffer g_ui8TxBuf to the (void *)(SSI1_BASE) using UDMA_CHANNEL_SSI1TX channel. The data is not transferred.
- Do i need to trigger using uDMAChannelRequest(UDMA_TRANSFER_CHANNEL); to transfer or uDMAChannelEnable(UDMA_TRANSFER_CHANNEL); is enough
- i'm not sure that to receive data at destination i used SSIDataGetNonBlocking is this proper way to receive data from SSI1 base.
Please find the code below :
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/udma.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/ssi.h"
#define CLK_FREQ 80000000
#define CLK_RATE 1000000
#define DATA_WIDTH 8
#define SSI_RXBUF_SIZE 256
#define UDMA_TRANSFER_CHANNEL UDMA_CHANNEL_SSI1TX
#define SSIDATA_FRAME_SIZE UDMA_SIZE_8
#define TIMES_DMA_TRANSFER UDMA_ARB_8
#define UDMA_TRANSFER_MODE UDMA_MODE_BASIC
#define SSI_TXBUF_SIZE 256
unsigned char g_ui8TxBuf[SSI_TXBUF_SIZE];
unsigned char pui8ControlTable[1024];
static unsigned char u32Rxdata[SSI_TXBUF_SIZE];
void init_uDMA();
void config_DMA_transfer();
void spi1_init()
{
unsigned int ui32SysClock;
ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN |SYSCTL_USE_OSC), CLK_FREQ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
GPIOPinTypeGPIOOutput(GPIO_PORTP_BASE, GPIO_PIN_0);
GPIOPinTypeGPIOOutput(GPIO_PORTP_BASE, GPIO_PIN_1);
GPIOPinConfigure(GPIO_PB4_SSI1FSS);
GPIOPinConfigure(GPIO_PB5_SSI1CLK);
GPIOPinConfigure(GPIO_PE4_SSI1XDAT0);
GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_5 | GPIO_PIN_4);
GPIOPinTypeSSI(GPIO_PORTE_BASE, GPIO_PIN_4);
SSIConfigSetExpClk(SSI1_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, CLK_RATE, DATA_WIDTH);
SSIEnable(SSI1_BASE);
printf("SPI Iniitiated sh1106 driver\n");
}
int main()
{
spi1_init();
//initialize uDMA module with transfer size of 16 bits
init_uDMA();
config_DMA_transfer();
uint_fast32_t i;
for(i = 0; i < SSI_TXBUF_SIZE; i++)
{
// Wait for data to be available in the receive buffer
while(SSIDataGetNonBlocking(SSI1_BASE, &u32Rxdata[i])) {}
}
//print on console
for(i = 0; i< SSI_TXBUF_SIZE; i++)
{
printf("u32Rxdata[%d] = %d\n", i, u32Rxdata[i]);
}
uDMADisable();
}
//*****************************************************************************
// initiate uDMA module and configure SSI for uDMA transfer
//*****************************************************************************
void init_uDMA()
{
printf("uDMA module initiating\n");
//called once to configure or initiate uDMA
//
// Enable the UDMA peripheral
//
printf("---- Enabling UDMA Peripheral----\n");
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
//
// Wait for the UDMA module to be ready.
//
printf("---- Waiting for UDMA Peripheral to ready----\n");
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA))
{
}
uDMAControlBaseSet(&pui8ControlTable[0]);
printf("uDMA channel control base set done\n");
//
// Put the attributes in a known state for the uDMA SSI1TX channel. These
// should already be disabled by default.
//
uDMAChannelAttributeDisable(UDMA_TRANSFER_CHANNEL,UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
//
// Set the USEBURST attribute for the uDMA SSI TX channel. This will
// force the controller to always use a burst when transferring data from
// the TX buffer to the UART. This is somewhat more efficient bus usage
// than the default which allows single or burst transfers.
//
uDMAChannelAttributeEnable(UDMA_TRANSFER_CHANNEL, UDMA_ATTR_USEBURST);
printf("uDMA channel attributes set done\n");
uDMAChannelControlSet(UDMA_TRANSFER_CHANNEL | UDMA_PRI_SELECT,
SSIDATA_FRAME_SIZE | UDMA_SRC_INC_8 |
UDMA_DST_INC_NONE | TIMES_DMA_TRANSFER);
printf("uDMA channel control set is done\n");
//enabling the uDMA module
uDMAEnable();
//
// Enable the uDMA interface for TX channel.
//
//
SSIDMAEnable(SSI1_BASE, SSI_DMA_TX); // transfer the control to uDMA controller
}
void config_DMA_transfer()
{
printf("SSI1 Transfering\n");
static uint_fast16_t ui16Idx;
//
// Fill the TX buffer with a simple data 0 to 255.
//
for(ui16Idx = 0; ui16Idx < SSI_TXBUF_SIZE; ui16Idx++)
{
g_ui8TxBuf[ui16Idx] = ui16Idx;
printf("g_ui8TxBuf %d\n", g_ui8TxBuf[ui16Idx]);
}
printf("DMA Transfer enabled\n");
//
// Set up the transfer parameters for the uDMA SSI TX channel. This will
// configure the transfer source and destination and the transfer size.
// Basic mode is used because the peripheral is making the uDMA transfer
// request. The source is the TX buffer and the destination is the SSI
// data register.
//
// Not transfering data from tx to SSI Base
uDMAChannelTransferSet(UDMA_TRANSFER_CHANNEL | UDMA_PRI_SELECT,
UDMA_TRANSFER_MODE, g_ui8TxBuf,
(void *)(SSI1_BASE),
sizeof(g_ui8TxBuf));
uDMAChannelEnable(UDMA_TRANSFER_CHANNEL);
printf("uDMA transfer channel enabled\n");
printf("--- Waiting to complete data transfer ---\n");
//wait for DMA transfer to complete
while(uDMAChannelIsEnabled(UDMA_TRANSFER_CHANNEL)) {}
printf("\n--- Transfer completed ---\n");
}
Thank you in Advance