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.

F2837x spi slave with dma without usìng interrupts: is it possible ?

Other Parts Discussed in Thread: CONTROLSUITE

Hallo everyone

I need to synchronize 2 processor with spi;

 master is tiva microcontroller tm4c and F2837x is slave; master and slave are exchanging 128-words arrays 

I tried the test code from controlSuite and if works fine , but i would like to know if it is possible to have everything working in the same way without using interrupts on the F2837x (LaunchPad board)

May you help on this ?I paste code here:

//C:\TI\controlSUITE\device_support\F2837xS\v180\F2837xS_examples_Cpu1
//###########################################################################
// FILE:   Example_2837xS_Spi_dma.c
// TITLE:  SPI with DMA Example. Slave
// buffer out starts from 1111 ,HALT=1 commented,continous mode on
//! \addtogroup cpu01_example_list
//! <h1>SPI  with DMA (spi_loopback_dma)</h1>
//!
//!  This program uses the internal loop back test mode of the peripheral.
//!  Other then boot mode pin configuration, no other hardware configuration
//!  is required. Both DMA Interrupts and the SPI FIFOs are used.
//!
//!  A stream of data is sent and then compared to the received stream.
//!  The sent data looks like this: \n
//!  0000 0001 \n
//!  0001 0002 \n
//!  0002 0003 \n
//!  .... \n
//!  007E 007F \n
//!
//!  \b Watch \b Variables \n
//!  - \b sdata - Data to send
//!  - \b rdata - Received data
//!  - \b rdata_point - Used to keep track of the last position in
//!    the receive stream for error checking
//
//###########################################################################
// $TI Release: F2837xS Support Library v180 $
// $Release Date: Fri Nov  6 16:27:58 CST 2015 $
// $Copyright: Copyright (C) 2014-2015 Texas Instruments Incorporated -
//             http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################

#include "F28x_Project.h"     // Device Headerfile and Examples Include File
#define INTERRUPT_ON
// Prototype statements for functions found within this file.

#ifdef INTERRUPT_ON
__interrupt void local_D_INTCH5_ISR(void);
__interrupt void local_D_INTCH6_ISR(void);
#endif
void delay_loop(void);
void dma_init(void);
void spi_fifo_init(void);
void error();
void myInitSpiaGpio();

Uint16 sdata[128];     // Send data buffer
Uint16 rdata[128];     // Receive data buffer
Uint16 rdata_point;  // Keep track of where we are
                     // in the data stream to check received data
Uint16 transfer_cycles =0;
// DMA data sections
#pragma DATA_SECTION(sdata, "ramgs0");	// map the TX data to memory
#pragma DATA_SECTION(rdata, "ramgs1");	// map the RX data to memory

volatile Uint16 *DMADest;
volatile Uint16 *DMASource;

#define BURST 		(FIFO_LVL-1)    // burst size should be less than 8
#define TRANSFER  	15 				// [(MEM_BUFFER_SIZE/FIFO_LVL)-1]
#define FIFO_LVL 	8				// FIFO Interrupt Level

volatile Uint16 done;


void main(void)
{
   Uint16 i;

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xS_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the F2837xS_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example
// Setup only the GP I/O only for SPI-A functionality
//   InitSpiaGpio();
   myInitSpiaGpio();
#ifdef INTERRUPT_ON
// Step 3. Initialize PIE vector table:
// Disable and clear all CPU interrupts
   DINT;
   IER = 0x0000;
   IFR = 0x0000;

// Initialize PIE control registers to their default state:
// This function is found in the F2837xS_PieCtrl.c file.
   InitPieCtrl();

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in F2837xS_DefaultIsr.c.
// This function is found in F2837xS_PieVect.c.
   InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
   EALLOW;  // This is needed to write to EALLOW protected registers
   PieVectTable.DMA_CH5_INT= &local_D_INTCH5_ISR;
   PieVectTable.DMA_CH6_INT= &local_D_INTCH6_ISR;
   EDIS;   // This is needed to disable write to EALLOW protected registers
#endif
// Step 4. Initialize the Device Peripherals:
   dma_init();			// set up dma for SPI configuration
   spi_fifo_init();		// Initialize the SPI only

	// Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected)
	EALLOW;
	CpuSysRegs.SECMSEL.bit.PF2SEL = 1;
	EDIS;


// Step 5. User specific code, enable interrupts:

	// Initialize the data buffers
	for(i=0; i<128; i++)
	{
		sdata[i] = i+1111;
		rdata[i]= 0;
	}
	rdata_point = 0;
#ifdef INTERRUPT_ON
// Enable interrupts required for this example
   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
   PieCtrlRegs.PIEIER7.bit.INTx5 = 1;	// Enable PIE Group 7, INT 1 (DMA CH5)
   PieCtrlRegs.PIEIER7.bit.INTx6 = 1;	// Enable PIE Group 7, INT 2 (DMA CH6)
   IER= M_INT7;							// Enable CPU INT6
   EINT;                                // Enable Global Interrupts

#endif

   StartDMACH6();		// Start SPI RX DMA channel
   StartDMACH5();		// Start SPI TX DMA channel

   EALLOW;
   DmaRegs.CH6.MODE.bit.CONTINUOUS=1;//continous mode
   DmaRegs.CH5.MODE.bit.CONTINUOUS=1;
   EDIS;

   while(1){//autorepeat
#ifdef INTERRUPT_ON
   done = 0;			// Test is not done yet

   while(!done);		// wait until the DMA transfer is complete
   //DELAY_US(1000000);
#endif
   transfer_cycles++;
#ifndef INTERRUPT_ON
   sdata[0]++;
#endif
   }

   // when the DMA transfer is complete the program will stop here
  // ESTOP0;

}

// Some Useful local functions
void delay_loop()
{
    long      i;
    for (i = 0; i < 1000000; i++) {}
}

void error(void)
{
   asm("     ESTOP0");  //Test failed!! Stop!
    for (;;);
}

void spi_fifo_init()
{
	int m;

	// FIFO configuration
	SpiaRegs.SPIFFCT.all=0x0;			    // place SPI in reset
	for(m=0;m<3;m++);
	SpiaRegs.SPIFFRX.all=0x2040;		    // RX FIFO enabled, clear FIFO int
	SpiaRegs.SPIFFRX.bit.RXFFIL = FIFO_LVL;	// Set RX FIFO level
	SpiaRegs.SPIFFTX.all=0xE040;		    // FIFOs enabled, TX FIFO released,
	SpiaRegs.SPIFFTX.bit.TXFFIL = FIFO_LVL;	// Set TX FIFO level

	// SPI configuration
	SpiaRegs.SPICCR.all = 0x000F ;		// SPI in reset, POL=0, 16bit words
	SpiaRegs.SPICTL.all = 0b0000000000000010;// 0x0006 ;		// TX enable, slave
	//SpiaRegs.SPIBRR.all = 0x63;		    // LSPCLK/100 //superfluo se slave
	SpiaRegs.SPICCR.all = 0b0000000010001111;//0x009F ; // Release SPI from Reset, no loopback
}

// DMA setup for both TX and RX channels.
void dma_init()
{
	// refer to dma.c for the descriptions of the following functions.

	//Initialize DMA
	DMAInitialize();

	DMASource = (volatile Uint16 *)sdata;
	DMADest = (volatile Uint16 *)rdata;

	// configure DMACH5  for TX
	DMACH5AddrConfig(&SpiaRegs.SPITXBUF,DMASource);
	DMACH5BurstConfig(BURST,1,0);			// Burst size, src step, dest step
	DMACH5TransferConfig(TRANSFER,1,0);		// transfer size, src step, dest step
	DMACH5ModeConfig(DMA_SPIATX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE
			,SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);

	// configure DMA CH2 for RX
	DMACH6AddrConfig(DMADest,&SpiaRegs.SPIRXBUF);
	DMACH6BurstConfig(BURST,0,1);
	DMACH6TransferConfig(TRANSFER,0,1);
	DMACH6ModeConfig(DMA_SPIARX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,
			SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);

}

#ifdef INTERRUPT_ON
// INT7.1
__interrupt void local_D_INTCH5_ISR(void)		// DMA Ch5 TX
{
	EALLOW;									// NEED TO EXECUTE EALLOW INSIDE ISR !!!
	//DmaRegs.CH5.CONTROL.bit.HALT=1;//halts the DMA at the current state and any current readwrite access is completed.
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts from this PIE group
	EDIS;
	sdata[0]++;
	return;
}


// INT7.2
__interrupt void local_D_INTCH6_ISR(void)		// DMA Ch6 RX
{
	Uint16 i;
	EALLOW;									// NEED TO EXECUTE EALLOW INSIDE ISR !!!
	//DmaRegs.CH6.CONTROL.bit.HALT = 1;
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts from this PIE group
	EDIS;

	done =1;		// test done.
	return;
}
#endif

void myInitSpiaGpio()//eval board
{
   EALLOW;

    //
    // Enable internal pull-up for the selected pins
    //
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.
    //
   // Enable pull-up
    GpioCtrlRegs.GPBPUD.bit.GPIO58 = 1;

    GpioCtrlRegs.GPBPUD.bit.GPIO59 = 1;

    GpioCtrlRegs.GPBPUD.bit.GPIO60 = 1;
    GpioCtrlRegs.GPBPUD.bit.GPIO61 = 1;

    //
    // Set qualification for selected pins to asynch only
    //
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO58 (SPISIMOA)

    GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO59 (SPISOMIA)

    GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO60 (SPICLKA)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO61 (SPISTEA)

    //
    //Configure SPI-A pins using GPIO regs
    //
    // This specifies which of the possible GPIO pins will be SPI functional
    // pins.
    // Comment out other unwanted lines.
    //

    GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO58 as SPISIMOA

    GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO59 as SPISOMIA

    GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO60 as SPICLKA
    GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO61 as SPISTEA

    GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO58 as SPISIMOA

    GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3; // Configure GPIO59 as SPISOMIA

    GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3; // Configure GPIO60 as SPICLKA
    GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO61 as SPISTEA

    GpioCtrlRegs.GPBDIR.bit.GPIO59=1;	// Configure GPIO59 as SPISOMIA as output

    EDIS;

    //Initialize GPIOs for the LEDs and turn them off
    EALLOW;
//    GpioCtrlRegs.GPADIR.bit.GPIO12 = 1;
    GpioCtrlRegs.GPADIR.bit.GPIO13 = 1;
//    GpioDataRegs.GPADAT.bit.GPIO12 = 1;
    GpioDataRegs.GPADAT.bit.GPIO13 = 1;
    EDIS;
}

  • Hi Carlo,

    Yes, that should be possible. Does it not work for you? Can you give me a bit more detail about what the issue is?

    Whitney
  • Hi Whitney
    No problem

    Master is a Tm4C1294 and slave is F8376D (production board ) or Delfino Launchpad for test and development

    The code you see above only works with interrupts on (there is a #define for disabling that)
    I tried to disable interrupts and use PERINT_DISABLE option but i do not receive anything from dsp at master side

    Maybe there is some other switch that i am missing ?

    regards

    Carlo
  • To be more clear, Arm is receiving the same numbers it is sending , dsp is not doing anything
  • On top of that SYNC_DISABLE , SYNC_SRC fields are not used in the DMACHXModeConfig function; is it normal ?
  • Carlo,

    You can configure this example to run without interrupts. I don't have this example modified for myself, but there is nothing preventing this to work. If you take the dma example, you will want to make sue that the SPI configuration does not change. You do need to interrupts from the SPI to trigger the dma.

    If you are just trying to wait on receiving the full data, you can just not enable the dma interrupt, but poll on the DMA CONTROL TRANSFERSTS bit to be 0, indicating that there is no active transmission.

    Regards,
    Mark
  • Carlo,

    Can you use the register view in CCS to try to get some status information that can help us debug the issue? For example, if you look at DMA ch 5 registers, can you tell whether or not a transfer has been triggered? Can you pull up the SPI TX FIFO registers and look at the buffers and FIFO status?

    If you look at the data lines on a scope or a logic analyzer, what do you see?

    Regarding the DMA sync options--those parameters applied to older devices but don't have any effect on the F2837xD. They were left there for software compatibility, but the actual hardware feature isn't there. You don't need to worry about it.

    Thanks,
    Whitney
  • Thank you Mark and Withney for all the help; it seems to partially work with chint_disabled and perint_enabled (send and receive data) with static data

    I do not see what i expect when i change array content in real time but this might be my fault or debugger settings (debug contrl register FREE maybe)

    I need to slightly change my code and then i will get back to you

    regards

    Carlo
  • Carlo,

    Have you gotten around to modifying your code and trying out our suggestions?

    -Mark
  • Carlo, I am going to close this post. If you have additional queries. please create a new post and link if necessary.