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