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 Name | GPIO Pin | SPI Module |
---|---|---|
SSI0CLK | PA2 | SPI0 |
SSI0Fss | PA3 | SPI0 |
SSI0Rx | PA4 | SPI0 |
SSI0Tx | PA5 | SPI0 |
SSI1CLK | PF2/PD0 | SPI1 |
SSI1Fss | PF3/PD1 | SPI1 |
SSI1Rx | PF0/PD2 | SPI1 |
SSI1Tx | PF1/PD3 | SPI1 |
SSI2CLK | PB4 | SPI2 |
SSI2Fss | PB5 | SPI2 |
SSI2Rx | PB6 | SPI2 |
SSI2Tx | PB7 | SPI2 |
SSI3CLK | PD0 | SPI3 |
SSI3Fss | PD1 | SPI3 |
SSI2Rx | PD2 | SPI3 |
SSI3Tx | PD3 | SPI3 |
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 Name | Function |
---|---|
RCGCSSI | Enable SPI module |
RCGCGPIO | Enable Clock to respective pins used for SPI communication |
GPIOAFSEL | Enable alternative function of GPIO pins |
GPIOPCTL | Select alternate function of GPIO pins for SPI communication |
GPIODEN | Set GPIO pins as digital pins |
SSICR1 | Used to enable SPI module and master/slave configuration |
SSICC | Enable system clock frequency to SPI module |
SSICPSR | System clock pre-divisor setting |
SSICR0 | Define 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.

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.

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:
- I2C Communication TM4C123G Tiva C Launchpad
- UART Communication TM4C123
- UART Interrupt TM4C123G Tiva C Launchpad
Other Tutorials:
- PWM TM4C123
- SPI Communication with PIC microcontroller
- UART Communication with Pic Microcontroller
- Use UART Interrupt of Pic Microcontroller
- UART Serial communication with MSP430 microcontroller
Other SPI tutorials:
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 .