Tiva-C LaunchPad GPIO Pin as a Digital Input – Reading Push Button

Keywords:Embedded systems, ARM, TM4C123GXL, GPIO

Code Link: Source Code Github Keil MDK5 – ARM Assembly

In the previous tutorial we introduced GPIOs and demonstrated how to configure GPIO Pin as a Digital output. This tutorial is almost similar the previous tutorial except in this tutorial we will configure GPIO Pin as an input to read on-board push button. TM4C123GXL LaunchPad consists of two user push button i.e. SW1, SW2 (see Figure-1) connected to PF.4 and PF.0 respectively. For the purpose of demonstration we will use SW2 connected to GPIOF pin-0 (PF.0).

Figure-1: TI TM4C123GXL Launchpad

Tutorial Scenario:

In this tutorial we will configure PF.0 as a digital Input to read on-board push button (SW2) connected to it. From TM4C123GXL reference manual, the on-board SW2 is connected to PF.0 pin as shown in Figure-2. Upon button press, the on-board Red LED is turned ON and upon release the LED is turned OFF.

This tutorial has three main parts.

Figure-2: Red LED and SW2 interfacing to GPIO PF.0,1

This tutorial has three main parts.

  1. Configuring PF.1 as a Digital output for Red LED covered in previous tutorial and here as well.
  2. Configuring PF.0 as a Digital input for reading push button SW2. This is covered in this tutorial.
  3. Reading Push button and turning LED ON/OFF.

Following are the tutorial steps.

1. GPIOx Port Bus Selection:

Each GPIO Module/Port is interfaced on one/more of SoC internal buses. Buses carry data between various peripherals and Core inside SoC. In TM4C123GXL Launchpad Port A-F are interfaced on APB bus while Ports K-N and P-Q are available on the AHB bus – see Figure 1-1 in Datasheet [2].

APB is Advanced Peripheral Bus while AHB is Advanced High Speed Bus. AHB has high throughput and performance as compared to APB which is the legacy version of AHB bus architecture.

The first step is to select bus for the desired Port (Port-F in our case). A port bus can be selected via GPIO High-Performance Bus Control (GPIOHBCTL) Register-Figure-3.

Figure-3: GPIO High-Performance Bus Control (GPIOHBCTL)

  • 0: APB bus selected
  • 1: AHB bus selected

As we mentioned earlier only Ports K-N and P-Q are available on the AHB bus so we have no choice for Port-F other than APB bus. So Let’s select APB bus for Port-F.


; use APB bus for GPIOF
LDR		R0,	[R1]
AND		R0,	R0, 	#0x1F  ; clear bit-5
STR		R0,	[R1]

2. GPIOx Clock:

To reduce power consumption, by default various SoC modules (GPIO, USART, UART etc.) and associated registers are disabled. In order to use them, clock must be enabled to them. On TM4C123GH6PM clock to various GPIOs can enabled/disabled via Run Mode Clock Gating Control Register 2 (RCGC2) – Figure-4.

Figure-4: Run Mode Clock Gating Control Register 2 (RCGC2)

As can be seen from Figure-2, the clock to GPIO Port-F is enabled/disabled via bit-5 (GPIOD-EN). Let’s enable Port-F module by setting bit-5 to 1.


; enable clock to GPIO-F
LDR		R0,	[R1] 
ORR		R0, 	R0, #0x20
STR		R0,	[R1]

3. GPIOx Pin Direction:

Any GPIO pin can be configured a Digital input or output. Before a GPIO pin is used, its direction needs to be configured appropriately. In our case as we want to read SW2 (connected to PF.0) and blink on-board Red LED (connected to PF.1), so the SW2 pin PF.0 needs to be configured as an Input while the LED pin PF.0 needs to be configured as an output. GPIO pins direction can be selected via GPIO Direction (GPIODIR) Register – Figure-5.

Figure-5: GPIO Direction (GPIODIR) Register

  • 0: Corresponding pin is an input.
  • 1: Corresponding pin is an output.

In our case let’s configure PF.0 as input by writing 0 to bit position 0 while PF.1 as an output by writing 1 to bit position 1.


; set PF.0 as input, PF.1 direction as output
MOV		R0,		#0x02
STR		R0,		[R1]

4. Unlock GPIOx Pin:

There are quite large number of peripherals available on compact size TM4C123GH6PM. Almost all of there peripherals have to capability to interact with outside world using I/O. Due to the compact size, not every peripheral can be assigned a dedicated physical pin on SoC due to size constrains. To accommodate these peripherals on SoC, various peripherals are multiplexed on a single I/O pin. At a time a pin be configured to be used dedicatedly for a specific peripheral.

For example PA.0,PA.1 pins can be configured to be used as Digital I/O or UART0 Tx, Rx respectively as an alternate function. In order to Lock a pin for specific purpose/function, TM4C123GH6PM implements software based hardware lock mechanism via GPIO Lock (GPIOLOCK) Register – Figure-6.

Figure-6: GPIO Lock (GPIOLOCK) Register

The GPIOLOCK register enables write access to the GPIO Commit (GPIOCR) Register register (discussed later). Writing 0x4C4F434B to the GPIO Lock (GPIOLOCK) register unlocks the GPIO Commit (GPIOCR) Register register. Writing any other value to the GPIOLOCK register re-enables the locked state.

Let’s unlock GPIO Commit (GPIOCR) Register.

; gpio registers

; register values

; unlock GPIOCR Register for write access
STR		R0,		[R1]

5. GPIOx Pin Functionality Unlock:

Once GPIO Commit (GPIOCR) Register – Figure-7, is unlocked. Its time to define:
1. Pins State (Pull-UP/Down),
2. Digital Functionalities (Digital I/O or Alternate function).

The GPIO Commit (GPIOCR) Register enables various registers (PIOAFSEL, GPIOPUR, GPIOPDR, and GPIODEN register) to configure a pin for above specifications. The GPIO Commit (GPIOCR) Register can only be written when its unlocked via GPIO Lock (GPIOLOCK) – previous step.

Figure-7: GPIO Commit (GPIOCR) Register

  • 0: The corresponding GPIOAFSEL, GPIOPUR, GPIOPDR, or GPIODEN bits cannot be written for respective pin.
  • 1: The corresponding GPIOAFSEL, GPIOPUR, GPIOPDR, or GPIODEN bits can be written for respective pin.

Let’s enable GPIOAFSEL, GPIOPUR, GPIOPDR, and GPIODEN for PF.0 (SW2 Pin) and PF.1 (LED Pin) – Figure-2.

; gpio registers

LDR		R0,	[R1]
ORR		R0, 	R0, 	#0x03
STR		R0,	[R1]

6. GPIOx Pin state:

The GPIO pin can be internally pulled-up or pulled-down thus setting the default Pin state to HIGH or LOW respectively. When pulled-high, the GPIO pin will remain in HIGH state until it is pulled down Software/External source and vise versa.

Pull-up/down states are needed in situations where a pins needs to remain in some state before a transition to be detected as an event like UART start/stop bits or Push buttons.

This is the most important step of this tutorial which differentiate this tutorial from previous Blinky LED tutorial. If we look at the TM4C123GXL board reference manual, we will come to know that when push button (SW2) is pressed, it connects PF.0 to ground – Figure-8. What this means is in order to detect button press on PF.0, PF.0 needs to be at logic-1 by default i.e the default state pin state should be high; when push button is pressed the PF.0 will get connected to ground and 0 will appear on PF.0 which we need to track.

Figure-8: SW2 connection to PF.0 and Ground

The GPIO pin pull-up/down state can be selected via GPIO Pull-Up Select (GPIOPUR) and GPIO Pull-Down Select (GPIOPDR) respectively registers – Figure-9,10.

Figure-9: GPIO Pull-Up Select (GPIOPUR)

Figure-9: GPIO Pull-Up Select (GPIOPUR)

Note: Setting a bit in the GPIOPUR register automatically clears the corresponding bit in the GPIOPDR register.

Let’s set pull-up GPIO PF.0 pin high.


; pull up PF.0
LDR		R0,		[R1]
ORR		R0, 	R0, 	#0x01
STR		R0,		[R1]

7. GPIOx Pin Digital Enable:

By default digital function is disabled for GPIOx Pins. They do not drive a Digital value appear on GPIO pin. To use the pin as a digital input or output (either GPIO or alternate function), the corresponding GPIO Digital Enable (GPIODEN) – Figure-11, bit must be set appropriately.

Figure-11: GPIO Digital Enable (GPIODEN)

  • 0: The digital functions for the corresponding pin are disabled.
  • 1: The digital functions for the corresponding pin are enabled.

Let’s enable Digital functionality for PF.0-1.

; gpio registers

; enable digital functionality for PF.0-1
MOV		R0,		#0x03
STR		R0,		[R1]

8. Digital Read/Write:

By now we configured everything we need. The last step is to write/read 0,1 i.e (Pin Low, High) to/from desired configured GPIO pin. GPIO pins can be read/written via GPIO Data (GPIODATA) register – Figure-12. The same register is used for both read/write operations.

Figure-12: GPIO Data (GPIODATA)

  • 0: The digital is set Low.
  • 1: The digital is set High.

NOTE: The GPIODATA has only one address but this register is virtually mapped to 256 locations in the address space i.e. GPIODATA + 0, GPIODATA+0x1, …. GPIODATA+0xFF. Each location is capable of setting Digital data to single pin depending on GPIODATA[9:2] address bits. The address bits 2-9 are associated with Digital pins 0-7 – Figure-13.
During a write, if the address bit associated with that data bit is set, the value of the GPIODATA register is altered. If the address bit is cleared, the data bit is left unchanged. For example, writing a value of 0xEB to the address GPIODATA + 0x098 has the results shown in Figure 13, where u indicates that data is unchanged by the write. This example demonstrates how GPIODATA bits 5, 2, and 1 are written.

Figure-13: GPIO Data (GPIODATA) address bits association with data bits

Similarly during a read, if the address bit associated with the data bit is set, the value is read. If the address bit associated with the data bit is cleared, the data bit is read as a zero, regardless of its actual value.

For GPIOF, the GPIODATA base address (for APB bus) is: 0x40025000. As we need to read from PF.0 pin which corresponds to bit-2 in address bits; and write to PF.1 pin which from Figure-13 corresponds to bit-3. so bit-2,3 needs to be set in order for read/write operation to be effective. so the address of GPIODATA register for GPIOF Pin-0,1 will be 0x4002500C (bit-2,3 set).

; gpio registers

Finally we reached a point where actually tutorial can be implemented. As per tutorial requirements, RED LED (PF.1) needs to be turned ON on SW2 press and Turn OFF on SW2 release. The functionality is achieved via the following code snippet.

	; read data register value for PF.0
	LDR		R0, 	[R1]				
	AND		R0, 	R0,		#0x1				
	CMP 	R0, 	#0x1				
	BNE		LED_ON	; if button is press, jump to LED_LED otherwise turn OFF LED

	; turn OFF LED
	AND 	R0,		R0,		#0x01
	STR		R0, 	[R1]
	B		loop
	; turn ON LED
	ORR		R0, 	R0, 	#0x02				
	STR		R0, 	[R1]
	B		loop	   ; jump back to loop

For complete source code refer to the Github links given at the start of this tutorial.

Video Demonstration:


290 thoughts on “Tiva-C LaunchPad GPIO Pin as a Digital Input – Reading Push Button”

Leave a Reply

Your email address will not be published. Required fields are marked *