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; }