Part Number: TMS320F28377S
Other Parts Discussed in Thread: CONTROLSUITE
Hello,
I am having issue, SPI-B is not working along with DMA. I have copied spi_loopback_dma_cpu01 from ControlSUITE example which is for SPI-A and make changes as following but I am not getting any signal out.
I have just replaced all spia with spib and change GPIOs accordingly. I have tried to troubleshoot but not able to get what is missing. Please help.
//###########################################################################
// FILE: Example_2837xS_Spi_dma.c
// TITLE: SPI Digital Loop Back with DMA Example.
//
//! \addtogroup cpu01_example_list
//! <h1>SPI Digital Loop Back 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 v190 $
// $Release Date: Mon Feb 1 16:59:09 CST 2016 $
// $Copyright: Copyright (C) 2014-2016 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
#include "F28x_Project.h" // Device Headerfile and Examples Include File
#include "spi.h"
// Prototype statements for functions found within this file.
__interrupt void local_D_INTCH5_ISR(void);
__interrupt void local_D_INTCH6_ISR(void);
void delay_loop(void);
void dma_init(void);
void spi_fifo_init(void);
void error();
void SPI_delay_us(long i);
void InitSpibGpio(void);
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
// 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
InitSpibGpio();
// 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
// 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;
rdata[i]= 0;
}
rdata_point = 0;
// 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 CH1)
PieCtrlRegs.PIEIER7.bit.INTx6 = 1; // Enable PIE Group 7, INT 2 (DMA CH2)
IER= M_INT7; // Enable CPU INT6
EINT; // Enable Global Interrupts
StartDMACH6(); // Start SPI RX DMA channel
StartDMACH5(); // Start SPI TX DMA channel
done = 0; // Test is not done yet
while(!done); // wait until the DMA transfer is complete
// 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
SpibRegs.SPIFFCT.all=0x0; // place SPI in reset
for(m=0;m<3;m++);
SpibRegs.SPIFFRX.all=0x2040; // RX FIFO enabled, clear FIFO int
SpibRegs.SPIFFRX.bit.RXFFIL = FIFO_LVL; // Set RX FIFO level
SpibRegs.SPIFFTX.all=0xE040; // FIFOs enabled, TX FIFO released,
SpibRegs.SPIFFTX.bit.TXFFIL = FIFO_LVL; // Set TX FIFO level
// SPI configuration
SpibRegs.SPICCR.all = 0x000F ; // SPI in reset, POL=0, 16bit words
SpibRegs.SPICTL.all = 0x0006 ; // TX enable, Master
SpibRegs.SPIBRR.all = 0x63; // LSPCLK/100
SpibRegs.SPICCR.all = 0x008F ; // Release SPI from Reset, enable LB mode
}
// 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(&SpibRegs.SPITXBUF,DMASource);
DMACH5BurstConfig(BURST,1,0); // Burst size, src step, dest step
DMACH5TransferConfig(TRANSFER,1,0); // transfer size, src step, dest step
DMACH5ModeConfig(DMA_SPIBTX,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,&SpibRegs.SPIRXBUF);
DMACH6BurstConfig(BURST,0,1);
DMACH6TransferConfig(TRANSFER,0,1);
DMACH6ModeConfig(DMA_SPIBRX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,
SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);
}
// INT7.1
__interrupt void local_D_INTCH5_ISR(void) // DMA Ch5
{
EALLOW; // NEED TO EXECUTE EALLOW INSIDE ISR !!!
DmaRegs.CH5.CONTROL.bit.HALT=1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts from this PIE group
EDIS;
return;
}
// INT7.2
__interrupt void local_D_INTCH6_ISR(void) // DMA Ch6
{
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;
for( i = 0; i<128; i++ )
{
// check for data integrity
if (rdata[i] != i)
{
// error();
}
}
done =1; // test done.
return;
}
//
// InitSpibGpio - Initialize SPIB GPIOs
//
void InitSpibGpio(void)
{
EALLOW;
GpioCtrlRegs.GPBPUD.bit.GPIO63 = 0; // Enable pull-up on GPIO16 (SPISIMOA)
// GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // Enable pull-up on GPIO5 (SPISIMOA)
GpioCtrlRegs.GPCPUD.bit.GPIO64 = 0; // Enable pull-up on GPIO17 (SPISOMIA)
// GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0; // Enable pull-up on GPIO3 (SPISOMIA)
GpioCtrlRegs.GPCPUD.bit.GPIO65 = 0; // Enable pull-up on GPIO18 (SPICLKA)
GpioCtrlRegs.GPCPUD.bit.GPIO66 = 0; // Enable pull-up on GPIO19 (SPISTEA)
/* 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.GPIO63 = 3; // Asynch input GPIO16 (SPISIMOA)
// GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3; // Asynch input GPIO5 (SPISIMOA)
GpioCtrlRegs.GPCQSEL1.bit.GPIO64 = 3; // Asynch input GPIO17 (SPISOMIA)
// GpioCtrlRegs.GPAQSEL1.bit.GPIO3 = 3; // Asynch input GPIO3 (SPISOMIA)
GpioCtrlRegs.GPCQSEL1.bit.GPIO65 = 3; // Asynch input GPIO18 (SPICLKA)
GpioCtrlRegs.GPCQSEL1.bit.GPIO66 = 3; // Asynch input GPIO19 (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.GPBMUX2.bit.GPIO63 = 1; // Configure GPIO16 as SPISIMOA
// GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2; // Configure GPIO5 as SPISIMOA
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 1; // Configure GPIO17 as SPISOMIA
// GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 2; // Configure GPIO3 as SPISOMIA
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 1; // Configure GPIO18 as SPICLKA
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 1; // Configure GPIO19 as SPISTEA
EDIS;
}
void SPI_delay_us(long i)
{
i = i * 12;
while(i>0)
{
i--;
}
}
Thank you,
Jaydeep