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.

SPI Comunication Error



Hello every body. I am new in Stellaris Launchpad.

I have a Stellaris Launchpad board run SPI in Master mode and another Stellaris Launchpad run SPI in Slave Mode. Master will send data then Slave receive data then echo it back to master. Then I monitor result via uart port. I have read example then do it. But I get an error. Data is lost. Every body can help me ?. What is an error ?

THIS IS MASTER CODE

//*****************************************************************************

#include "inc/hw_memmap.h"
#include "inc/hw_ssi.h"
#include "inc/hw_types.h"
#include "driverlib/ssi.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "utils/uartstdio.h"



//*****************************************************************************
//
// Number of bytes to send and receive.
//
//*****************************************************************************
#define NUM_SSI_DATA 3

//*****************************************************************************
//
// This function sets up UART0 to be used for a console to display information
// as the example is running.
//
//*****************************************************************************
void
InitConsole(void)
{
//
// Enable GPIO port A which is used for UART0 pins.
// TODO: change this to whichever GPIO port you are using.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

//
// Configure the pin muxing for UART0 functions on port A0 and A1.
// This step is not necessary if your part does not support pin muxing.
// TODO: change this to select the port/pin you are using.
//
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);

//
// Select the alternate (UART) function for these pins.
// TODO: change this to select the port/pin you are using.
//
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

//
// Initialize the UART for console I/O.
//
UARTStdioInit(0);
}

//*****************************************************************************
//
// Configure SSI0 in master Freescale (SPI) mode. This example will send out
// 3 bytes of data, then wait for 3 bytes of data to come in. This will all be
// done using the polling method.
//
//*****************************************************************************
int
main(void)
{
unsigned long ulDataTx[NUM_SSI_DATA];
unsigned long ulDataRx[NUM_SSI_DATA];
unsigned long ulindex;

//
// Set the clocking to run directly from the external crystal/oscillator.
// TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
// crystal on your board.
//

SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
//
// Set up the serial console to use for displaying messages. This is
// just for this example program and is not needed for SSI operation.
//
InitConsole();

//
// Display the setup on the console.
//
UARTprintf("SSI ->\n");
UARTprintf(" Mode: SPI\n");
UARTprintf(" Data: 8-bit\n\n");

//
// The SSI0 peripheral must be enabled for use.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);

//
// For this example SSI0 is used with PortA[5:2]. The actual port and pins
// used may be different on your part, consult the data sheet for more
// information. GPIO port A needs to be enabled so these pins can be used.
// TODO: change this to whichever GPIO port you are using.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

//
// Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5.
// This step is not necessary if your part does not support pin muxing.
// TODO: change this to select the port/pin you are using.
//
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA4_SSI0RX);
GPIOPinConfigure(GPIO_PA5_SSI0TX);

//
// Configure the GPIO settings for the SSI pins. This function also gives
// control of these pins to the SSI hardware. Consult the data sheet to
// see which functions are allocated per pin.
// The pins are assigned as follows:
// PA5 - SSI0Tx
// PA4 - SSI0Rx
// PA3 - SSI0Fss
// PA2 - SSI0CLK
// TODO: change this to select the port/pin you are using.
//
GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
GPIO_PIN_2);

//
// Configure and enable the SSI port for SPI master mode. Use SSI0,
// system clock supply, idle clock level low and active low clock in
// freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.
// For SPI mode, you can set the polarity of the SSI clock when the SSI
// unit is idle. You can also configure what clock edge you want to
// capture data on. Please reference the datasheet for more information on
// the different SPI modes.
//
SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
SSI_MODE_MASTER, 1000000, 8);

//
// Enable the SSI0 module.
//
SSIEnable(SSI0_BASE);

//
// Read any residual data from the SSI port. This makes sure the receive
// FIFOs are empty, so we don't read any unwanted junk. This is done here
// because the SPI SSI mode is full-duplex, which allows you to send and
// receive at the same time. The SSIDataGetNonBlocking function returns
// "true" when data was returned, and "false" when no data was returned.
// The "non-blocking" function checks if there is any data in the receive
// FIFO and does not "hang" if there isn't.
//
while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]))
{
}

//
// Initialize the data to send.
//
ulDataTx[0] = 's';
ulDataTx[1] = 'p';
ulDataTx[2] = 'i';

//
// Display indication that the SSI is transmitting data.
//
UARTprintf("Sent:\n ");

//
// Send 3 bytes of data.
//
for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)
{
//
// Display the data that SSI is transferring.
//
UARTprintf("'%c' ", ulDataTx[ulindex]);

//
// Send the data using the "blocking" put function. This function
// will wait until there is room in the send FIFO before returning.
// This allows you to assure that all the data you send makes it into
// the send FIFO.
//
SSIDataPut(SSI0_BASE, ulDataTx[ulindex]);
}

//
// Wait until SSI0 is done transferring all the data in the transmit FIFO.
//
while(SSIBusy(SSI0_BASE))
{
}

//
// Display indication that the SSI is receiving data.
//
UARTprintf("\nReceived:\n ");

//
// Receive 3 bytes of data.
//
for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)
{
//
// Receive the data using the "blocking" Get function. This function
// will wait until there is data in the receive FIFO before returning.
//
SSIDataGet(SSI0_BASE, &ulDataRx[ulindex]);

//
// Since we are using 8-bit data, mask off the MSB.
//
ulDataRx[ulindex] &= 0x00FF;

//
// Display the data that SSI0 received.
//
UARTprintf("'%c' ", ulDataRx[ulindex]);
}

//
// Return no errors
//
return(0);
}

THIS IS SLAVE CODE

 

#include "inc/hw_memmap.h"
#include "inc/hw_ssi.h"
#include "inc/hw_types.h"
#include "driverlib/ssi.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
main()
{
unsigned long data;
SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);


SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA4_SSI0RX);
GPIOPinConfigure(GPIO_PA5_SSI0TX);
GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
GPIO_PIN_2);
SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
SSI_MODE_SLAVE, 1000000, 8);
SSIEnable(SSI0_BASE);


//Read all residual data in fifo receiver

while(SSIDataGetNonBlocking(SSI0_BASE, &data));


while(1)
{

//Receiver data then echo it back to master
SSIDataGet(SSI0_BASE, &data);
SSIDataPut(SSI0_BASE,data);
while(SSIBusy(SSI0_BASE));
}
}

THIS IS SCREEN CAPTURE

  • You are using SPI0 for both master and slave mode. Could that be the problem?

    Thanks,
    Sai
  • Poster notes that he has 2 launchpads - thus use of SPI_0 (on both devices) seems ok.

    If we are to believe that his "screen shot" is/was "real" - he's captured the first 2 of the SPI bytes sent by the Master - and echoed those correctly.

    As always - Unguided Posters omit key/critical detail. Reported were, "I get an error" and "data is lost." Rarely is there description of the "error" and which data has been lost...

    Relying upon rushed, frustrated posters to, "touch all necessary bases" has long proved ineffective - (continues) to waste time, effort, space...
  • My apologies for not reading the post correctly and overlooking the fact the two different LaunchPads are being used.

    cbi,
    Thanks for pointing it out.

    Nguyen,
    Did you try looking if the SPI master has received more data than what is being printed on the console? The "Master Code" is restricting the number of bytes it can print to 3.

    Regards,
    Sai
  • I thank you for your comment .
    The master code i get from example of the Stellaris Ware Library. I have the feeling that
    the Transmit FIFO of Master is not empty before transmit .
  • Nguyen Xuan Thiep said:
    I have the feeling that the Transmit FIFO of Master is not empty before transmit .

    That may well prove true.   And - cannot you devise an experiment to test for that (empty) condition?   Or assume "not empty" - and create some work-around...

    Did you actually receive those 2 (correct) bytes from the Slave @ your Master?  (that establishes great progress - already achieved...)

  • This actually looks right to me, you send three bytes and receive back 3 bytes. The first byte you receive back must be a default (or undefined value) since you have not yet received a byte in the slave to echo yet. The last byte sent cannot be echoed since you end the transaction.

    I am, however, left with the question I always have when seeing SPI used in this manner. Why SPI? SPI appears to be the least desirable communication method for this purpose.

    Robert
  • Yes Robert - you/I appear to be in agreement.

    Poster (only) states, "I get an error" and "data is lost." (what error & which data - from those "unguided" - most always fails to arrive...)