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.

TMS320F28379D: Delfino SPI DMA TX Not Working

Part Number: TMS320F28379D


I am using the TMS320F28379D as a SPI slave. I have code running to the point where I can receive my test data plenty fine, but the data I am expecting to be sent out by the Delfino is never being sent. The data I do see getting sent out appears to be an echo of the received data, but shifted by a single word. I am currently using a dummy 6 word array for both my master and slave. I can provide any register information or scope traces if needed.

Can someone please review my setup code to make sense of what's going on? I am expecting to see my sdata clocked out as my master is sending me the test array of words.

This is my Delfino setup code:

///	Defines the FIFO trigger level in number of words
#define SPI_SUPER_FIFO_LVL          1
///	Defines the number of words to transfer in a single burst
#define SPI_SUPER_BURST             SPI_SUPER_FIFO_LVL
///	Defines the number of bursts to transfer
#define SPI_SUPER_TRANSFER_SIZE     6

//	Globals
#pragma DATA_SECTION("ramgs0");     //	TODO - does this need to be mapped?
uint16_t sdata[6] = { 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F };
#pragma DATA_SECTION("ramgs1");     //	TODO - does this need to be mapped?
uint16_t rdata[6] = { 0x00 };

//	Function Prototypes
__interrupt void SPI_MS_to_SUP_TX_DMA_Interrupt( void );
__interrupt void SPI_MS_to_SUP_RX_DMA_Interrupt( void );

/// \author Bryan Radke
/// \brief Initializes the SPI interface to the supervisor processor
/// \param none
/// \return none
///
///	Initializes a DMA slave setup. The supervisor is the master.
void Init_SPI_MS_to_SUP( void )
{
	//	SPI module must be disabled before configuration
	SPI_disableModule( SPIA_BASE );

	//	SPI clock does not matter since we are the slave. Setup SPI for 16bit data size.
	SPI_setConfig( SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_SLAVE, 3000000, 16 );

	//	We are communicating with the supervisor processor so loopback needs to be disabled
	SPI_disableLoopback( SPIA_BASE );

	//	Enable the FIFO for configuration
	SPI_enableFIFO( SPIA_BASE );

	//	Clear any pending FIFO interrupts before setup/enabling new interrupts
	SPI_clearInterruptStatus( SPIA_BASE, SPI_INT_TXFF | SPI_INT_RXFF );

	//	Setup the TX and RX FIFO to trigger when a single word has been transmitted/received
	SPI_setFIFOInterruptLevel( SPIA_BASE, SPI_FIFO_TX1, SPI_FIFO_RX1 );

	//	Enable the TX and RX FIFO interrupts
	//SPI_enableInterrupt( SPIA_BASE, SPI_INT_TXFF | SPI_INT_RXFF );

	//	Configuration is complete so enable the SPI module
	SPI_enableModule( SPIA_BASE );

	//	Setup DMA channel 5 for sending data to the supervisor
	DMA_configAddresses( DMA_CH5_BASE, (uint16_t *)(SPIA_BASE + SPI_O_TXBUF), sdata );

	//	Configure the TX DMA burst size based on the FIFO levels used
	DMA_configBurst( DMA_CH5_BASE, SPI_SUPER_BURST, 1, 0 );

	//	Configure the TX DMA transfer size based on the data to send and the burst size
	DMA_configTransfer( DMA_CH5_BASE, SPI_SUPER_TRANSFER_SIZE, 1, 0 );

	//	Configure the TX DMA for continue trigger mode based on TX of data
	DMA_configMode( DMA_CH5_BASE, DMA_TRIGGER_SPIATX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );

	//	Configure the TX DMA to interrupt at the end of transmission
	DMA_setInterruptMode( DMA_CH5_BASE, DMA_INT_AT_END );

	//	Register the TX DMA interrupt handler
	Interrupt_register( DMA_CH5_BASE, &SPI_MS_to_SUP_TX_DMA_Interrupt );

	//	Enable the TX DMA interrupt
	DMA_enableInterrupt( DMA_CH5_BASE );

	//	Enable the TX DMA to allow a start of transfer
	DMA_enableTrigger( DMA_CH5_BASE );

	//	Setup DMA channel 6 for receiving data from the supervisor
	DMA_configAddresses( DMA_CH6_BASE, rdata, (uint16_t *)( SPIA_BASE + SPI_O_RXBUF ) );

	//	Configure the RX DMA burst size based on the FIFO levels used
	DMA_configBurst( DMA_CH6_BASE, SPI_SUPER_BURST, 0, 1 );

	//	Configure the RX DMA transfer size based on the data to send and the burst size
	DMA_configTransfer( DMA_CH6_BASE, SPI_SUPER_TRANSFER_SIZE, 0, 1 );

	//	Configure the RX DMA for continue trigger mode based on RX of data
	DMA_configMode( DMA_CH6_BASE, DMA_TRIGGER_SPIARX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );

	//	Configure the RX DMA to interrupt at the end of transmission
	DMA_setInterruptMode( DMA_CH6_BASE, DMA_INT_AT_END );

	//	Register the RX DMA interrupt handler
	Interrupt_register( INT_DMA_CH6, &SPI_MS_to_SUP_RX_DMA_Interrupt );

	//	Enable the RX DMA interrupt
	DMA_enableInterrupt( DMA_CH6_BASE );

	//	Enable the RX DMA to allow a start of transfer
	DMA_enableTrigger( DMA_CH6_BASE );
}

__interrupt void SPI_MS_to_SUP_TX_DMA_Interrupt( void )
{
	Interrupt_clearACKGroup( INTERRUPT_ACK_GROUP7 );
}

__interrupt void SPI_MS_to_SUP_RX_DMA_Interrupt( void )
{
	if ( rdata[0] != 0 )
	{
		rdata[0] = 0;
	}
	Interrupt_clearACKGroup( INTERRUPT_ACK_GROUP7 );
}

  • This was not captured in my original post, but I am enabling the DMA channel 5 and 6 interrupts after calling Init_SPI_MS_to_SUP. After enabling the DMA channels, I am then starting the channels before enabling INTM and DBGM.

  • Bryan,

    Thanks for reaching out to the E2E.

    Due to inclement weather in our region, many of our subject matter experts are without power and unable to provide support at this time.  An expert will get back to you as soon as possible but it likely will not be until next week.

    Best,

    Matthew

  • The code below now has the TX data going out, but the first TX is essentially an echo of the RX data, and subsequent transmissions are my TX data, but again shifted a word.

    ///	Defines the FIFO trigger level in number of words
    #define SPI_SUPER_FIFO_LVL          1
    ///	Defines the number of words to transfer in a single burst
    #define SPI_SUPER_BURST             SPI_SUPER_FIFO_LVL
    ///	Defines the number of bursts to transfer
    //#define SPI_SUPER_TRANSFER_SIZE     ( sizeof( S_MS_to_Super_IPC_TEST ) / SPI_SUPER_BURST )
    #define SPI_SUPER_TRANSFER_SIZE     8
    
    //	Globals
    #pragma DATA_SECTION("ramgs0");     //	TODO - does this need to be mapped?
    uint16_t sdata[8] = { 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x9F, 0xAF };
    #pragma DATA_SECTION("ramgs1");     //	TODO - does this need to be mapped?
    uint16_t rdata[8] = { 0x00 };
    
    void Init_SPI_MS_to_SUP( void )
    {
    	//	SPI module must be disabled before configuration
    	SPI_disableModule( SPIA_BASE );
    
    	//	Enable the FIFO for configuration
    	SPI_enableFIFO( SPIA_BASE );
    
    	//	Clear any pending FIFO interrupts before setup/enabling new interrupts
    	SPI_clearInterruptStatus( SPIA_BASE, SPI_INT_TXFF | SPI_INT_RXFF );
    
    	//	Setup the TX and RX FIFO to trigger when a single word has been transmitted/received
    	SPI_setFIFOInterruptLevel( SPIA_BASE,
    	                           (SPI_TxFIFOLevel)SPI_SUPER_FIFO_LVL,
    	                           (SPI_RxFIFOLevel)SPI_SUPER_FIFO_LVL );
    
    	//	SPI clock does not matter since we are the slave. Setup SPI for 16bit data size.
    	SPI_setConfig( SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_SLAVE, 3000000, 16 );
    
    	//	We are communicating with the supervisor processor so loopback needs to be disabled
    	SPI_disableLoopback( SPIA_BASE );
    
    	//	Configuration is complete so enable the SPI module
    	SPI_enableModule( SPIA_BASE );
    
    	//	Initialize DMA
    	DMA_initController();
    
    	//	Setup DMA channel 5 for sending data to the supervisor
    	DMA_configAddresses( DMA_CH5_BASE, (uint16_t *)( SPIA_BASE + SPI_O_TXBUF ), sdata );
    
    	//	Configure the TX DMA burst size based on the FIFO levels used
    	DMA_configBurst( DMA_CH5_BASE, SPI_SUPER_BURST, 1, 0 );
    
    	//	Configure the TX DMA transfer size based on the data to send and the burst size
    	DMA_configTransfer( DMA_CH5_BASE, SPI_SUPER_TRANSFER_SIZE, 1, 0 );
    
    	//	Configure the TX DMA for continue trigger mode based on TX of data
    	DMA_configMode( DMA_CH5_BASE, DMA_TRIGGER_SPIARX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );
    
    	//	Configure the TX DMA to interrupt at the end of transmission
    	DMA_setInterruptMode( DMA_CH5_BASE, DMA_INT_AT_BEGINNING );
    
    	//	Register the TX DMA interrupt handler
    	Interrupt_register( INT_DMA_CH5, &SPI_MS_to_SUP_TX_DMA_Interrupt );
    
    	//	Enable the TX DMA interrupt
    	DMA_enableInterrupt( DMA_CH5_BASE );
    
    	//	Enable the TX DMA to allow a start of transfer
    	DMA_enableTrigger( DMA_CH5_BASE );
    
    	//	Setup DMA channel 6 for receiving data from the supervisor
    	DMA_configAddresses( DMA_CH6_BASE, rdata, (uint16_t *)( SPIA_BASE + SPI_O_RXBUF ) );
    
    	//	Configure the RX DMA burst size based on the FIFO levels used
    	DMA_configBurst( DMA_CH6_BASE, SPI_SUPER_BURST, 0, 1 );
    
    	//	Configure the RX DMA transfer size based on the data to send and the burst size
    	DMA_configTransfer( DMA_CH6_BASE, SPI_SUPER_TRANSFER_SIZE, 0, 1 );
    
    	//	Configure the RX DMA for continue trigger mode based on RX of data
    	DMA_configMode( DMA_CH6_BASE, DMA_TRIGGER_SPIARX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );
    
    	//	Configure the RX DMA to interrupt at the end of transmission
    	DMA_setInterruptMode( DMA_CH6_BASE, DMA_INT_AT_END );
    
    	//	Register the RX DMA interrupt handler
    	Interrupt_register( INT_DMA_CH6, &SPI_MS_to_SUP_RX_DMA_Interrupt );
    
    	//	Enable the RX DMA interrupt
    	DMA_enableInterrupt( DMA_CH6_BASE );
    
    	//	Enable the RX DMA to allow a start of transfer
    	DMA_enableTrigger( DMA_CH6_BASE );
    }

  • Forcing a DMA channel 5 (TX) trigger after configuration resulted in my TX data being sent our properly for two transactions. From that point forward, my TX data appears to be stepping by a size of 2 words (skipping every other word). My step size is still 1 word and I have been reviewing the DMA state diagram in the tech. reference manual. I was not explicitly defining a wrap size, but even adding a forced step size did not correct the issue where words are skipped.

  • Hi Bryan,

    Please take a look at the following formulas to define the DMA transfer and burst size found in the TRM within the SPI Chapter.

    Transmit: 

    DMA_TRANSFER_SIZE: (NUM_WORDS /TXFFIL) – 1 

    DMA_BURST_SIZE: (16 – TXFFIL) – 1

    Receive: 

    DMA_TRANSFER_SIZE: (NUM_WORDS /RXFFIL) – 1 

    DMA_BURST_SIZE = RXFFIL-1 

    For your configuration the receive side seems to be configured correctly. DMA receive channel transfer size of (8/1)-1= 7 (8 transfers) and a burst size of (1-1)=0 (1 word per burst).

    I would suggest changing the TXFILL to 8 instead of 1. This way your transfer size is (8/8)-1=0 (1 transfer) and your burst size is (16-8)-1= 7 (8 words per burst). 

    Best Regards,

    Marlyn

  • Hello Marlyn,

    I attempted to set my TX FIFO level to 8 like you suggested, but it still does not work. Our data payload will not always be even divisible by 8, so I don't know if that would have worked for our end application either way. I have added my updated code below to show my current setup.

    On the first transmission, I see 0x8A and 0x8B sent from the DSP, but the remaining six bytes are all of value 0x8A (not aligning with my dummy send array). Any subsequent request from the master will result in the DSP only sending 0x8A. I can see the channel 5 BURST_SIZE was set to 7 as expected. The TRANSFER_SIZE is set to zero as expected. The SRC_BURST_STEP is 1 and the SRC_TRANSFER_STEP is 1. The DMA's shadow addresses are both pointing to the start of my dummy array which is also expected.

    I had to add the DMA_forceTrigger to get valid data sent out the first time the master started a transfer. Without this force trigger, the DSP slave would only send out 0x00.

    ///	Defines the TX FIFO trigger level in number of words
    #define SPI_SUPER_TX_FIFO_LVL			8
    ///	Defines the number of words to transfer in a single burst
    #define SPI_SUPER_TX_BURST				SPI_SUPER_TX_FIFO_LVL
    ///	Defines the number of bursts to transfer
    //#define SPI_SUPER_TX_TRANSFER_SIZE		( sizeof( S_MS_to_Super_IPC_TEST ) / SPI_SUPER_TX_BURST )
    #define SPI_SUPER_TX_TRANSFER_SIZE		( 8 / SPI_SUPER_TX_FIFO_LVL )
    
    ///	Defines the RX FIFO trigger level in number of words
    #define SPI_SUPER_RX_FIFO_LVL			1
    ///	Defines the number of words to transfer in a single burst
    #define SPI_SUPER_RX_BURST				SPI_SUPER_RX_FIFO_LVL
    ///	Defines the number of bursts to transfer
    //#define SPI_SUPER_RX_TRANSFER_SIZE		( sizeof( S_MS_to_Super_IPC_TEST ) / SPI_SUPER_TX_BURST )
    #define SPI_SUPER_RX_TRANSFER_SIZE		( 8 / SPI_SUPER_RX_FIFO_LVL )
    
    //	Globals
    #pragma DATA_SECTION("ramgs0");     //	TODO - does this need to be mapped?
    uint16_t sdata[8] = { 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x9F, 0xAF };
    #pragma DATA_SECTION("ramgs1");     //	TODO - does this need to be mapped?
    uint16_t rdata[8] = { 0x00 };
    
    //	Function Prototypes
    __interrupt void SPI_MS_to_SUP_TX_DMA_Interrupt( void );
    __interrupt void SPI_MS_to_SUP_RX_DMA_Interrupt( void );
    
    /// \author Bryan Radke
    /// \brief Initializes the SPI interface to the supervisor processor
    /// \param none
    /// \return none
    ///
    ///	Initializes a DMA slave setup. The supervisor is the master.
    void Init_SPI_MS_to_SUP( void )
    {
    	//	Register the RX DMA interrupt handler
    	Interrupt_register( INT_DMA_CH6, &SPI_MS_to_SUP_RX_DMA_Interrupt );
    
    	//	Register the TX DMA interrupt handler
    	Interrupt_register( INT_DMA_CH5, &SPI_MS_to_SUP_TX_DMA_Interrupt );
    
    	//	Initialize DMA
    	DMA_initController();
    
    	//	Setup DMA channel 5 for sending data to the supervisor
    	DMA_configAddresses( DMA_CH5_BASE, (uint16_t *)( SPIA_BASE + SPI_O_TXBUF ), sdata );
    
    	//	Configure the TX DMA burst size based on the FIFO levels used
    	DMA_configBurst( DMA_CH5_BASE, SPI_SUPER_TX_BURST, 1, 0 );
    
    	//	Configure the TX DMA transfer size based on the data to send and the burst size
    	DMA_configTransfer( DMA_CH5_BASE, SPI_SUPER_TX_TRANSFER_SIZE, 1, 0 );
    
    	//	Configure the TX DMA for continue trigger mode based on TX of data
    	DMA_configMode( DMA_CH5_BASE, DMA_TRIGGER_SPIARX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );
    
    	//	Configure the TX DMA to interrupt at the end of transmission
    	DMA_setInterruptMode( DMA_CH5_BASE, DMA_INT_AT_BEGINNING );
    
    	//	Enable the TX DMA interrupt
    	DMA_enableInterrupt( DMA_CH5_BASE );
    
    	//	Enable the TX DMA to allow a start of transfer
    	DMA_enableTrigger( DMA_CH5_BASE );
    
    	//	Setup DMA channel 6 for receiving data from the supervisor
    	DMA_configAddresses( DMA_CH6_BASE, rdata, (uint16_t *)( SPIA_BASE + SPI_O_RXBUF ) );
    
    	//	Configure the RX DMA burst size based on the FIFO levels used
    	DMA_configBurst( DMA_CH6_BASE, SPI_SUPER_RX_BURST, 0, 1 );
    
    	//	Configure the RX DMA transfer size based on the data to send and the burst size
    	DMA_configTransfer( DMA_CH6_BASE, SPI_SUPER_RX_TRANSFER_SIZE, 0, 1 );
    
    	//	Configure the RX DMA for continue trigger mode based on RX of data
    	DMA_configMode( DMA_CH6_BASE, DMA_TRIGGER_SPIARX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );
    
    	//	Configure the RX DMA to interrupt at the end of transmission
    	DMA_setInterruptMode( DMA_CH6_BASE, DMA_INT_AT_END );
    
    	//	Enable the RX DMA interrupt
    	DMA_enableInterrupt( DMA_CH6_BASE );
    
    	//	Enable the RX DMA to allow a start of transfer
    	DMA_enableTrigger( DMA_CH6_BASE );
    
    	//	Enable the FIFO for configuration
    	SPI_enableFIFO( SPIA_BASE );
    
    	//	Clear any pending FIFO interrupts before setup/enabling new interrupts
    	SPI_clearInterruptStatus( SPIA_BASE, SPI_INT_TXFF | SPI_INT_RXFF );
    
    	//	Setup the TX and RX FIFO to trigger when a single word has been transmitted/received
    	SPI_setFIFOInterruptLevel( SPIA_BASE,
    	                           (SPI_TxFIFOLevel)SPI_SUPER_TX_FIFO_LVL,
    	                           (SPI_RxFIFOLevel)SPI_SUPER_RX_FIFO_LVL );
    	//	SPI module must be disabled before configuration
    	SPI_disableModule( SPIA_BASE );
    
    	//	SPI clock does not matter since we are the slave. Setup SPI for 16bit data size.
    	SPI_setConfig( SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_SLAVE, 3000000, 16 );
    
    	//	We are communicating with the supervisor processor so loopback needs to be disabled
    	SPI_disableLoopback( SPIA_BASE );
    
    	//	Configuration is complete so enable the SPI module
    	SPI_enableModule( SPIA_BASE );
    
    	//	TEST
    	DMA_forceTrigger( DMA_CH5_BASE );
    }
    
    __interrupt void SPI_MS_to_SUP_TX_DMA_Interrupt( void )
    {
    	Interrupt_clearACKGroup( INTERRUPT_ACK_GROUP7 );
    }
    
    __interrupt void SPI_MS_to_SUP_RX_DMA_Interrupt( void )
    {
    	if ( rdata[0] != 0 )
    	{
    		rdata[0] = 0;
    	}
    	Interrupt_clearACKGroup( INTERRUPT_ACK_GROUP7 );
    }

  • Bryan,

    Curious as to why you you configured the TX DMA to interrupt at the beginning of transmission and not the end?

    Can you please monitor the TXFFST bits of the SPIFFTX register using the expressions window in CCS?

    Also, are you monitoring the data that is being transmitted using an oscilloscope/logic analyzer or are you viewing it on your master device?  

    Best Regards,

    Marlyn

  • Hi Marlyn,

    The TX DMA interrupt at the start of transmission was just me testing things. It doesn't need to be at the start. However, it did help me see the TXFFST once I ran the force trigger function.

    After the force trigger, the TX DMA interrupt is called, I can see TXFFST set to 0b00111 and my TXFFIL set to 0b01000 which is good. That means the DMA should function?

    Once my RX DMA interrupt is called, I see that TXFFST is set to 0b10000 and TXFFIL is still set to 0b01000...

    I am looking at the data on an oscilloscope with a SPI analyzer. The output data running my last code is 0x008A 008B 008A 008A 008A 008A 008A 008A for the first transfer. Any subsequent transfer results in all output words set to 0x008A.

    Bryan

  • Hi Bryan,

    I just noticed that in your latest code when you configure DMA channel 5 (TX) you are setting the trigger source to DMA_TRIGGER_SPIARX, this should be changed to DMA_TRIGGER_SPIATX. 

    //  Configure the TX DMA for continue trigger mode based on TX of data
        DMA_configMode( DMA_CH5_BASE, DMA_TRIGGER_SPIARX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );

    Best Regards,

    Marlyn

  • Hi Marlyn,

    That was my issue with my garbled up TX data. I removed the forced trigger and I can now send over my dummy TX data, but there's still an odd concern I have.

    I have adjusted my code to have the last word in my dummy TX set to a value of 0. In my DMA RX interrupt, I am incrementing this value by 1 so I can see a good stream go between my master and slave. It takes 3 cycles from the master before I can see the last word in my dummy TX data set to a value of 1. I can pause the DSP debugger and can see that the word is actually a value of 4 (which is what I expected that word to be set to).

    What could be causing this odd shift? How can I fix this?

    /// Defines the TX FIFO trigger level in number of words
    #define SPI_SUPER_TX_FIFO_LVL           8
    /// Defines the number of words to transfer in a single burst
    #define SPI_SUPER_TX_BURST              SPI_SUPER_TX_FIFO_LVL
    /// Defines the number of bursts to transfer
    //#define SPI_SUPER_TX_TRANSFER_SIZE        ( sizeof( S_MS_to_Super_IPC_TEST ) / SPI_SUPER_TX_BURST )
    #define SPI_SUPER_TX_TRANSFER_SIZE      ( 8 / SPI_SUPER_TX_FIFO_LVL )
    
    /// Defines the RX FIFO trigger level in number of words
    #define SPI_SUPER_RX_FIFO_LVL           1
    /// Defines the number of words to transfer in a single burst
    #define SPI_SUPER_RX_BURST              SPI_SUPER_RX_FIFO_LVL
    /// Defines the number of bursts to transfer
    //#define SPI_SUPER_RX_TRANSFER_SIZE        ( sizeof( S_MS_to_Super_IPC_TEST ) / SPI_SUPER_RX_BURST )
    #define SPI_SUPER_RX_TRANSFER_SIZE      ( 8 / SPI_SUPER_RX_FIFO_LVL )
    
    //  Globals
    #pragma DATA_SECTION("ramgs0");     //  TODO - does this need to be mapped?
    uint16_t sdata[8] = { 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x9F, 0x00 };
    #pragma DATA_SECTION("ramgs1");     //  TODO - does this need to be mapped?
    uint16_t rdata[8] = { 0x00 };
    
    //  Function Prototypes
    __interrupt void SPI_MS_to_SUP_TX_DMA_Interrupt( void );
    __interrupt void SPI_MS_to_SUP_RX_DMA_Interrupt( void );
    
    /// \author Bryan Radke
    /// \brief Initializes the SPI interface to the supervisor processor
    /// \param none
    /// \return none
    ///
    /// Initializes a DMA slave setup. The supervisor is the master.
    void Init_SPI_MS_to_SUP( void )
    {
    	//  Register the RX DMA interrupt handler
    	Interrupt_register( INT_DMA_CH6, &SPI_MS_to_SUP_RX_DMA_Interrupt );
    
    	//  Register the TX DMA interrupt handler
    	Interrupt_register( INT_DMA_CH5, &SPI_MS_to_SUP_TX_DMA_Interrupt );
    
    	//  Initialize DMA
    	DMA_initController();
    
    	//  Setup DMA channel 5 for sending data to the supervisor
    	DMA_configAddresses( DMA_CH5_BASE, (uint16_t *)( SPIA_BASE + SPI_O_TXBUF ), sdata );
    
    	//  Configure the TX DMA burst size based on the FIFO levels used
    	DMA_configBurst( DMA_CH5_BASE, SPI_SUPER_TX_BURST, 1, 0 );
    
    	//  Configure the TX DMA transfer size based on the data to send and the burst size
    	DMA_configTransfer( DMA_CH5_BASE, SPI_SUPER_TX_TRANSFER_SIZE, 1, 0 );
    
    	//  Configure the TX DMA for continue trigger mode based on TX of data
    	DMA_configMode( DMA_CH5_BASE, DMA_TRIGGER_SPIATX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );
    
    	//  Configure the TX DMA to interrupt at the end of transmission
    	DMA_setInterruptMode( DMA_CH5_BASE, DMA_INT_AT_BEGINNING );
    
    	//  Enable the TX DMA interrupt
    	DMA_enableInterrupt( DMA_CH5_BASE );
    
    	//  Enable the TX DMA to allow a start of transfer
    	DMA_enableTrigger( DMA_CH5_BASE );
    
    	//  Setup DMA channel 6 for receiving data from the supervisor
    	DMA_configAddresses( DMA_CH6_BASE, rdata, (uint16_t *)( SPIA_BASE + SPI_O_RXBUF ) );
    
    	//  Configure the RX DMA burst size based on the FIFO levels used
    	DMA_configBurst( DMA_CH6_BASE, SPI_SUPER_RX_BURST, 0, 1 );
    
    	//  Configure the RX DMA transfer size based on the data to send and the burst size
    	DMA_configTransfer( DMA_CH6_BASE, SPI_SUPER_RX_TRANSFER_SIZE, 0, 1 );
    
    	//  Configure the RX DMA for continue trigger mode based on RX of data
    	DMA_configMode( DMA_CH6_BASE, DMA_TRIGGER_SPIARX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT );
    
    	//  Configure the RX DMA to interrupt at the end of transmission
    	DMA_setInterruptMode( DMA_CH6_BASE, DMA_INT_AT_END );
    
    	//  Enable the RX DMA interrupt
    	DMA_enableInterrupt( DMA_CH6_BASE );
    
    	//  Enable the RX DMA to allow a start of transfer
    	DMA_enableTrigger( DMA_CH6_BASE );
    
    	//  Enable the FIFO for configuration
    	SPI_enableFIFO( SPIA_BASE );
    
    	//  Clear any pending FIFO interrupts before setup/enabling new interrupts
    	SPI_clearInterruptStatus( SPIA_BASE, SPI_INT_TXFF | SPI_INT_RXFF );
    
    	//  Setup the TX and RX FIFO to trigger when a single word has been transmitted/received
    	SPI_setFIFOInterruptLevel( SPIA_BASE,
    	                           (SPI_TxFIFOLevel)SPI_SUPER_TX_FIFO_LVL,
    	                           (SPI_RxFIFOLevel)SPI_SUPER_RX_FIFO_LVL );
    	//  SPI module must be disabled before configuration
    	SPI_disableModule( SPIA_BASE );
    
    	//  SPI clock does not matter since we are the slave. Setup SPI for 16bit data size.
    	SPI_setConfig( SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_SLAVE, 3000000, 16 );
    
    	//  We are communicating with the supervisor processor so loopback needs to be disabled
    	SPI_disableLoopback( SPIA_BASE );
    
    	//  Configuration is complete so enable the SPI module
    	SPI_enableModule( SPIA_BASE );
    }
    
    __interrupt void SPI_MS_to_SUP_TX_DMA_Interrupt( void )
    {
    	Interrupt_clearACKGroup( INTERRUPT_ACK_GROUP7 );
    }
    
    __interrupt void SPI_MS_to_SUP_RX_DMA_Interrupt( void )
    {
    	sdata[7]++;
    	Interrupt_clearACKGroup( INTERRUPT_ACK_GROUP7 );
    }

    Bryan

  • Hi Bryan,

    How much data is being sent by the master? Are you viewing both transmit and receive from master and slave devices in your oscilloscope?

    It might due to the RXFFIL and TXFFIL levels. You can always change these based on your application needs. 

    Best Regards,

    Marlyn

  • Hi Marlyn,

    The master is sending the same amount as my slave buffers are setup for. I am viewing the data on an oscilloscope and the scope is showing the same results as my slave. I have played around with the FIFO levels, and it's still the same issue. The slave will change data, but the change is not reflected on the SPI transmission until 3 cycles have taken place.

    Bryan

  • Hi Bryan,

    I just tested this on my end. If you set your SPI_SUPER_TX_FIFO_LVL value to 1 you should see the updated data get sent on the next transmission cycle. Please let me know if this isn't the case for you or if you had already tried that.

    Best Regards,

    Marlyn

  • Hi Marlyn,

    I just found this a half hour ago, but if I made my buffers to the point where I have more than one transfer everything works as expected (which is what you just reported). I am not sure what you'd like as the resolved answer here, but I really appreciate all of your help!

    Regards,

    Bryan