SPI Communication TM4C123 – Communication Between Tiva Launchpad and Arduino

In this tutorial, we will learn to use SPI communication modules of TM4C123 microcontroller using Tiva C Launchpad. As per the nomenclature of the TM4C123GH6PM microcontroller, the name used for SPI modules is a synchronous serial interface(SSI). But it is popularly referred to as a serial peripheral interface. That is why we will use the term SPI instead of SSI throughout this tutorial. Because SSI modules support three protocols such as TI serial interface, MICROWIRE, and SPI. First, we will learn to configure SPI modules through their registers. In the end, we will see an example of SPI communication between TM4C123G Tiva Launchpad and Arduino

TM4C123 SPI Modules

As you know that Tiva Launchpad comes with TM4C123GF6PM microcontroller. This microcontroller contains four serial peripheral interfaces or SPI modules. Each module can be configured in master or slave mode to receive or send data to other devices that communicate over SPI interface.SSI modules convert serial data into parallel data. 

Followings are the main features of TM4C123 SPI modules: 

  • Master and Slave Configuration 
  • FIFOs for each SPI transmitter and receiver
  • Direct SPI data transfer to DMA ( direct memory access controller) 

In this modern embedded systems era, many sensors such as mcp3008, ADCs, DACs, Temperature and pressure sensors etc, provide data over SPI communication. This way we can take off processor and microcontroller load of data acquisition and directly take data measurements from these sensors through SPI communication. 

SPI Modules Pins

As we mentioned earlier, TM4C123 microcontroller has four SPI modules. In order for SPI based devices to communicate with each other, four pins are required such as clock, serial data in, serial data out and frame signal. This table lists the external signals of each SPI module on GPIO pins of TM4C123 Tiva Launchpad. 

Pin NameGPIO PinSPI Module
SSI0CLKPA2SPI0
SSI0FssPA3SPI0
SSI0RxPA4SPI0
SSI0TxPA5SPI0
SSI1CLKPF2/PD0SPI1
SSI1FssPF3/PD1SPI1
SSI1RxPF0/PD2SPI1
SSI1TxPF1/PD3SPI1
SSI2CLKPB4SPI2
SSI2FssPB5SPI2
SSI2RxPB6SPI2
SSI2TxPB7SPI2
SSI3CLKPD0SPI3
SSI3FssPD1SPI3
SSI2RxPD2SPI3
SSI3TxPD3SPI3

TM4C123 SPI Configuration Registers 

These registers are used to configure SPI modules of TM4C123 in master and slave mode. This table lists configuration registers and their functions. 

Register NameFunction
RCGCSSI Enable SPI module
RCGCGPIOEnable Clock to respective pins used for SPI communication
GPIOAFSELEnable alternative function of GPIO pins
GPIOPCTLSelect alternate function of GPIO pins for SPI communication
GPIODENSet GPIO pins as digital pins
SSICR1Used to enable SPI module and master/slave configuration 
SSICCEnable system clock frequency to SPI module
SSICPSRSystem clock pre-divisor setting
SSICR0Define clock rate, phase and polarity, protocol mode

TM4C123 SPI Communication Code

This example code demonstrates the use of the SSI1 module of TM4C123GH6PM microcontroller in SPI mode. According to the above table, GPIO pins RD0, RD2, RD3 can be configured as CLK, transmit and receive pin for SPI1 communication module.

This code initializes and configures SPI1 module in master mode operating

at 4MHz clock frequency. In addition, 8-bit data size, mode 0 of SPI frame format are also configured. 

Inside the while loop, TM4C123 microntroller transmits character ‘A’ through SSI1Tx pin and waits for one second. After that, it transmits character ‘B’ and waits again for one second.

/* Example code to transmit data with SPI1 module of TM4C123 */
/* Transmits character A and B with a delay of one second */
#include "TM4C123GH6PM.h"

/* function prototype of SPI and Delay */
void SPI1_init(void);
void SPI1_Write(unsigned char data);
void Delay_ms(int time_ms); 

/* Main routine of code */
int main(void)
{
    unsigned char val1 = 'A';
	  unsigned char val2 = 'B';

    SPI1_init();
    while(1)
		{              
    SPI1_Write(val1); /* write a character */
    Delay_ms(1000);
		SPI1_Write(val2); /* write a character */
    Delay_ms(1000);	
    }
}

void SPI1_Write(unsigned char data)
{
    GPIOF->DATA &= ~(1<<2);       /* Make PF2 Selection line (SS) low */
    while((SSI1->SR & 2) == 0); /* wait untill Tx FIFO is not full */
    SSI1->DR = data;            /* transmit byte over SSI1Tx line */
    while(SSI1->SR & 0x10);     /* wait until transmit complete */
    GPIOF->DATA |= 0x04;        /* keep selection line (PF2) high in idle condition */
}

void SPI1_init(void)
{
    /* Enable clock to SPI1, GPIOD and GPIOF */
	
   	SYSCTL->RCGCSSI |= (1<<1);   /*set clock enabling bit for SPI1 */
    SYSCTL->RCGCGPIO |= (1<<3); /* enable clock to GPIOD for SPI1 */
    SYSCTL->RCGCGPIO |= (1<<5); /* enable clock to GPIOF for slave select */

    /*Initialize PD3 and PD0 for SPI1 alternate function*/
	
    GPIOD->AMSEL &= ~0x09;      /* disable analog functionality RD0 and RD3 */
    GPIOD->DEN |= 0x09;         /* Set RD0 and RD3 as digital pin */
    GPIOD->AFSEL |= 0x09;       /* enable alternate function of RD0 and RD3*/
    GPIOD->PCTL &= ~0x0000F00F; /* assign RD0 and RD3 pins to SPI1 */
    GPIOD->PCTL |= 0x00002002;  /* assign RD0 and RD3 pins to SPI1  */
    
    /* Initialize PF2 as a digital output as a slave select pin */
	
    GPIOF->DEN |= (1<<2);         /* set PF2 pin digital */
    GPIOF->DIR |= (1<<2);         /* set PF2 pin output */
    GPIOF->DATA |= (1<<2);        /* keep SS idle high */

    /* Select SPI1 as a Master, POL = 0, PHA = 0, clock = 4 MHz, 8 bit data */
		
    SSI1->CR1 = 0;          /* disable SPI1 and configure it as a Master */
    SSI1->CC = 0;           /* Enable System clock Option */
    SSI1->CPSR = 4;         /* Select prescaler value of 4 .i.e 16MHz/4 = 4MHz */
    SSI1->CR0 = 0x00007;     /* 4MHz SPI1 clock, SPI mode, 8 bit data */
    SSI1->CR1 |= 2;         /* enable SPI1 */
}

/* This function generates delay in ms */
/* calculations are based on 16MHz system clock frequency */

void Delay_ms(int time_ms)
{
    int i, j;
    for(i = 0 ; i < time_ms; i++)
        for(j = 0; j < 3180; j++)
            {}  /* excute NOP for 1ms */
}

void SystemInit(void)
{
    /* use this only if you are using old versions of Keil uvision */
    SCB->CPACR |= 0x00f00000;
}

For SPI master and slave devices to communicate with each other, they should have common parameters such as clock frequency, phase, SPHA, SPOL. In this TM4C123 SPI code, we configure SPI1 as a Master and operating frequency of 4MHz with POL = 0, PHA = 0. 

The reason we have chosen 4MHz frequency and both phase zero. Because we want to communicate between TM4C123 Tiva Launchpad and Arduino. The default parameters settings for Arduino SPI module are POL = 0, PHA = 0, clock = 4 MHz. Therefore, it makes parameters for both master and slave devices common.

SPI Communication with Arduino and TM4C123 Tiva Launchpad

To see the demonstration of the above code, we will perform SPI communication with TM4C123 Tiva Launchpad and Arduino. Tiva Launchpad will be configured as a master device and Arduino as a slave device. 

Arduino as a SPI Slave Device

In this example code of Arduino, Arduino acts as a slave device.

#include<SPI.h>
#define LEDpin 7
volatile boolean received;
char Slavereceived;
void setup()
{
  Serial.begin(9600);
  pinMode(LEDpin,OUTPUT);                 // Setting pin 7 as OUTPU
  SPCR |= (1<<SPE)| (1<<SPIE);            //Turn on SPI in Slave Mode
  received = false;
  SPI.attachInterrupt();                  //Interuupt ON is set for SPI commnucation
  sei();
}

ISR (SPI_STC_vect)                        //Inerrrput routine function 
{
  Slavereceived = SPDR;         // Value received from master if store in variable slavereceived
  received = true;                        //Sets received as True 
}

void loop()
{  
  if(received)   //Logic to SET LED ON OR OFF depending upon the value recerived from master
   {
      if (Slavereceived=='A') 
      {
        digitalWrite(LEDpin,HIGH);         //Sets pin 7 as HIGH LED ON
        Serial.println("Slave LED ON");
        Serial.println(Slavereceived);
      }
       else
      {
        digitalWrite(LEDpin,LOW);          //Sets pin 7 as LOW LED OFF
        Serial.println("Slave LED OFF");
        Serial.println(Slavereceived);
      } 
   }
   delay(1000);
}

Following pins of Arduino is used for SPI communication:

  • D10 -> SS
  • D11 -> MOSI
  • D12 -> MISO
  • D13 -> SCLK

Whenever data becomes available on the receive MOSI pin, Arduino reads this data and saves the data inside a receive slave variable. Inside the loop() function, this code checks if data is received by Arduino on the SPI receive pin. If received data is a character ‘A’, it will turn on an LED which is connected with the D7 pin of Arduino and also print this message on the Arduino serial monitor along with “LED IS ON” string. If data received is other than character A, LED will turn off and Arduino displays LED is OFF character on the serial monitor.

TM4C123 as a SPI Master Device

As we mentioned earlier, the above given TM4C123 microcontroller SPI code transmits A and B over the SPI1 transmitter pin with a delay of one second. Hence, Arduino which is acting as a slave receives the data from TM4C123 and makes decisions accordingly.

Connection Diagram

Now make the connections with TM4C123 Tiva Launchpad and Arduino according to this connection diagram. In this example, Tiva launchpad will act as a transmitter and Arduino as a receiver.

SPI Communication Between TM4C123 Tiva Launchpad and Arduino

Hardware Demo

Now upload Arduino code to Arduino Uno and TM4C123 code to Tiva Launchpad using Arduino IDE and Keil uvision respectively.

Now open the Arduino serial monitor. After that click on the reset button of the TM4C123 Tiva launchpad. You will notice that the LED, which is connected with the D7 pin of the Arduino, turns on and off with a one-second delay. Also, you will see the data received from TM4C123 on the serial monitor.

SPI Communication Between TM4C123 Tiva Launchpad and Arduino serial monitor output

In summary, we learned to use SPI communication modules of TM4C123 to communicate with other SPI based devices.

Video Demo

Other TM4C123 Serial Communication Tutorials:

Other Tutorials:

Other SPI tutorials:

1 thought on “SPI Communication TM4C123 – Communication Between Tiva Launchpad and Arduino”

  1. Hello,
    Sir can we transmit data from slave to master in here. Could you make update for this? For example, when tiva sent ‘A’, then arduino answer to tiva ‘done’ after tiva make next process .

    Reply

Leave a Comment