This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3200 continuous DMA with SPI slave.

Other Parts Discussed in Thread: CC3200

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
		}

    }

}