Hi.
I'm currently working on receiving series of packets on SPI slave using DMA.
During this process, I got some questions.
1. Continuous DMA is possible?
My DMA setting is as follows.
UDMASetupTransfer(UDMA_CH30_GSPI_RX,
UDMA_MODE_BASIC,
1023,
UDMA_SIZE_8,
UDMA_ARB_1,
(void *)(GSPI_BASE + MCSPI_O_RX0),
UDMA_SRC_INC_NONE,
g_testBuf,
UDMA_DST_INC_8);
And it seems working well. I can receive data in g_testBuf when there's SPI_INT_DMARX interrupt.
But, every time I get data through DMA I should set another DMA for the next transfaction.
I should call repeated UDMASetupTransfer() function whenever there's SPI_INT_DMARX interrupt.
Why do I have to call setup function manually?
I also find PingPong mode in DMA but it seems like it also need repeated setup inside SPI_INT_DMARX interrupt.
I don't want to change DMA settings, but I have to setup every time I use it. I think this is unnecessary.
2. Using with SPI-FIFO
I also setup SPI FIFO to trigger DMA when there's 16 byte in FIFO.
But I think I'm not understanding how SPI FIFO works.
My SPI FIFO setup is as follows.
//SPIWordCountSet(GSPI_BASE, 16);
SPIFIFOLevelSet(GSPI_BASE,1, 15);
SPIFIFOEnable(GSPI_BASE, SPI_RX_FIFO);
I have 16 bytes of data to receive and this data will be transmitted to CC3200 every few seconds.
And I wanted to trigger DMA when there's 16byte in SPI FIFO. (So I set AFL as 15)
I don't want to stop SPI channel so I didn't setup word count.
But SPI_INT_DMARX never triggered.
I think I'm misunderstand how AFL works.
In conslusion,
1. Continuous DMA is possible in SPI receive only?
2. How to trigger AFL event with SPI-FIFO setup. (on 16bytes in FIFO)
How to change it to achieve my goal?
I attached currently working source of continuous DMA rx without using FIFO.
Thanks for your time.
//*****************************************************************************
//
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
//
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
//*****************************************************************************
//
// Application Name - SPI Demo
// Application Overview - The demo application focuses on showing the required
// initialization sequence to enable the CC3200 SPI
// module in full duplex 4-wire master and slave mode(s).
// Application Details -
// http://processors.wiki.ti.com/index.php/CC32xx_SPI_Demo
// or
// docs\examples\CC32xx_SPI_Demo.pdf
//
//*****************************************************************************
//*****************************************************************************
//
//! \addtogroup SPI_Demo
//! @{
//
//*****************************************************************************
// Standard includes
#include <string.h>
// Driverlib includes
#include "hw_types.h"
#include "hw_memmap.h"
#include "hw_common_reg.h"
#include "hw_ints.h"
#include "spi.h"
#include "rom.h"
#include "rom_map.h"
#include "utils.h"
#include "prcm.h"
#include "uart.h"
#include "interrupt.h"
#include "gpio.h"
#include "pin.h"
#include "hw_mcspi.h"
#include "udma.h"
// Common interface includes
#include "uart_if.h"
#include "gpio_if.h"
#include "udma_if.h"
#include "pinmux.h"
#define APPLICATION_VERSION "1.1.1"
//*****************************************************************************
//
// Application Master/Slave mode selector macro
//
// MASTER_MODE = 1 : Application in master mode
// MASTER_MODE = 0 : Application in slave mode
//
//*****************************************************************************
#define MASTER_MODE 0
#define SPI_IF_BIT_RATE 100000
#define TR_BUFF_SIZE 100
#define MASTER_BUFFER_SIZE 1024
#define MASTER_MSG "This is CC3200 SPI Master Application\n\r"
#define SLAVE_MSG "This is CC3200 SPI Slave Application\n\r"
//*****************************************************************************
// GLOBAL VARIABLES -- Start
//*****************************************************************************
static unsigned char g_ucTxBuff[TR_BUFF_SIZE];
static unsigned char g_ucRxBuff[TR_BUFF_SIZE];
static unsigned char g_ucSPIbufferRx[MASTER_BUFFER_SIZE];
static unsigned char g_testBuf[16];
static unsigned char ucTxBuffNdx;
static unsigned char ucRxBuffNdx;
static unsigned char slave_dma_flag = false;
#if defined(ccs)
extern void (* const g_pfnVectors[])(void);
#endif
#if defined(ewarm)
extern uVectorEntry __vector_table;
#endif
//*****************************************************************************
// GLOBAL VARIABLES -- End
//*****************************************************************************
static void SlaveIntHandler()
{
unsigned long ulRecvData;
unsigned long ulStatus;
ulStatus = MAP_SPIIntStatus(GSPI_BASE,true);
MAP_SPIIntClear(GSPI_BASE,SPI_INT_DMARX);
if(ulStatus & SPI_INT_DMARX)
{
slave_dma_flag = true;
}
}
//*****************************************************************************
//
//! SPI Slave mode main loop
//!
//! This function configures SPI modelue as slave and enables the channel for
//! communication
//!
//! \return None.
//
//*****************************************************************************
void SlaveMain()
{
//
// Initialize the message
//
memcpy(g_ucTxBuff,SLAVE_MSG,sizeof(SLAVE_MSG));
//
// Set Tx buffer index
//
ucTxBuffNdx = 0;
ucRxBuffNdx = 0;
//
// Reset SPI
//
MAP_SPIReset(GSPI_BASE);
// Init DMA
UDMAInit();
Message("Init UDMA\n\r");
//
// Configure SPI interface
//
MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
(SPI_HW_CTRL_CS |
SPI_4PIN_MODE |
SPI_TURBO_OFF |
SPI_CS_ACTIVELOW |
SPI_WL_8));
UDMASetupTransfer(UDMA_CH30_GSPI_RX, //Channel - Set Peripheral - SPI Rx.
UDMA_MODE_BASIC, //Mode - Basic (Not fully understanded. Check on datasheet.)
1024, //SIZE - Items to be transfered (1~1024, byte based??->Data size can be set among 8,16,32)
UDMA_SIZE_8, // DMA size -> 8, 16, 32
UDMA_ARB_1, //ARB - Arbitration gap. ( Send until set count & do arbitration.)
(void *)(GSPI_BASE + MCSPI_O_RX0), //Src - SPI Rx FIFO address.
UDMA_SRC_INC_NONE, //Inc - SPI Peripheral Src Inc size - fixed to 8 (because SPI FIFO is 8.) so None.
g_testBuf, //Dst - buffer we created.
UDMA_DST_INC_8); //Inc - we get 8 bit so no reason not to use 8.
/*!!!!!!!!!!!!Something is wrong. not working with fifo. !!!!!!!!!!!!!!!!!!!!!*/
//SPIWordCountSet(GSPI_BASE, 16);
//SPIFIFOLevelSet(GSPI_BASE,1, 15);
//SPIFIFOEnable(GSPI_BASE, SPI_RX_FIFO);
MAP_SPIDmaEnable(GSPI_BASE,SPI_RX_DMA);
Message("DMA Enabled\n\r");
//
// Register Interrupt Handler
//
MAP_SPIIntRegister(GSPI_BASE,SlaveIntHandler);
//
// Enable Interrupts
//
//MAP_SPIIntEnable(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY|SPI_INT_DMARX);
MAP_SPIIntEnable(GSPI_BASE,SPI_INT_DMARX);
Message("DMA Interrupt Enabled\n\r");
//
// Enable SPI for communication
//
MAP_SPIEnable(GSPI_BASE);
//
// Print mode on uart
//
Message("Enabled SPI Interface in Slave Mode\n\rReceived : ");
}
//*****************************************************************************
//
//! Board Initialization & Configuration
//!
//! \param None
//!
//! \return None
//
//*****************************************************************************
static void
BoardInit(void)
{
/* In case of TI-RTOS vector table is initialize by OS itself */
#ifndef USE_TIRTOS
//
// Set vector table base
//
#if defined(ccs)
MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]);
#endif
#if defined(ewarm)
MAP_IntVTableBaseSet((unsigned long)&__vector_table);
#endif
#endif
//
// Enable Processor
//
MAP_IntMasterEnable();
MAP_IntEnable(FAULT_SYSTICK);
PRCMCC3200MCUInit();
}
//*****************************************************************************
//
//! Main function for spi demo application
//!
//! \param none
//!
//! \return None.
//
//*****************************************************************************
void main()
{
//
// Initialize Board configurations
//
BoardInit();
//
// Muxing UART and SPI lines.
//
PinMuxConfig();
//
// Enable the SPI module clock
//
MAP_PRCMPeripheralClkEnable(PRCM_GSPI,PRCM_RUN_MODE_CLK);
//
// Initialising the Terminal.
//
InitTerm();
//
// Clearing the Terminal.
//
ClearTerm();
//
// Display the Banner
//
Message("\n\n\n\r");
Message("\t\t ********************************************\n\r");
Message("\t\t CC3200 SPI Master DMA TEST \n\r");
Message("\t\t ********************************************\n\r");
Message("\n\n\n\r");
//
// Reset the peripheral
//
MAP_PRCMPeripheralReset(PRCM_GSPI);
SlaveMain();
int i =0;
while(1)
{
#if 1
if(slave_dma_flag)
{
slave_dma_flag = false;
for(i = 0; i< 16; i++) {
Report("%c," ,g_testBuf[i]);
}
Report("\r\n");
#endif
}
}
}