Lesson 10: GPIO Ports and Configurations
The microprocessors access their I/O (Input/Output) devices either by special I/O instructions that read and write to peripherals located in a separate I/O address space, called "Port Mapped I/O, PMIO", or using the instructions that are provided to access memory, called "Memory-mapped I/O, MMIO". ARM-based processors use memory-mapped I/O. The I/O ports share the same address space with memory. That means the software can access an I/O port simply by reading from or writing to the appropriate address, and these addresses are usually called "Registers". Most I/O ports can be configured into different I/O functions through the registers, you can find detailed information about I/O Registers from the microprocessor's datasheet.
Even the accessing I/O register "look" like reads and writes to memory variables, but there are still have some difference between the memory and I/O Registers. For example, some bits in the Register are read-only and some are write-only; some bits can only be cleared or set; some bits cannot be modified and some are reserved for future used.
General-Purpose Input/Output (GPIO)
GPIO is a generic pin on a microcontroller and is controllable by the program at run time. GPIO pins have no predefined purpose and can be operated as parallel interfaces, it allows the microcontroller to exchange digital information with external devices. For example, GPIO can be used for reading from a temperature sensor, and for writing output to an LCD module or LEDs for status.
GPIO pins have the following capabilities:
- GPIO pins can be configured to be input or output
- GPIO pins can be enabled or disabled
- Input values are readable( typically logic high or low)
- Output values are writable and can be read-back
- Input pin can be used to trigger the interrupt function
Instead of directly configuring and controlling each individual GPIO pin, we set up a group of GPIO pins (typically 8 GPIO pins) into a PORT. Through the PORT registers, we can control and access multiple GPIO pins at a time.
Texas Instruments Tiva TM4C I/O Ports
The GPIO on the Tiva TM4C family is extremely flexible. Any GPIO can be configured to different functions: it can be an interrupt, edge-triggered on rising, falling, or both; or it can be level-sensitive to high or low values.
Tiva C microcontroller is a low power ARM Cortex-M4 microprocessor and runs typically at 3.3V, so the logic levels of I/O pins are 3.3V. The drive strength of the outputs of the GPIO is programmable to be 2, 4, or 8 milliamps. All GPIO pins have programmable weak pull-up, pull-down, and open-drain modes.
- Never exceed the input logic high voltage of any pin beyond the VDD limit unless you are sure that the source will not exceed the limit voltage.
- Don't use negative input voltages with any pin. Be sure of polarity.
- Don't stress any GPIO pin beyond 10 ~ 15mA, although the max limit is 25mA. Use external switching devices like FETs, BJTs, and photo-isolators to drive high power loads.
GPIO Addressing Masking
GPIO Address masking is a somewhat unusual technique for programming the GPIO port pins. Each GPIO port has a base address, if you write an 8-bit value directly to this base address and all eight pins will be modified. If you just want to modify specific bits of this port, you would have to read the value on the port pins, change the specific bits, and then write the value back out to the port. This is called a read-modify-write operation and it's fraught with issues. For instance, if an interrupt changed at pin state in the middle of this process, your code would write the wrong value to the pin.
On the Tiva TM4C parts, you can use a bit-mask to indicate which bits are to be modified. This is done in hardware by mapping each GPIO port to 256 addresses, which can cover every possible combination of the port pins. Bits [9:2] of the address are used as the bit-mask.
For example, if we want to modify the value on GPIO Port D pin 1, 2, and 5 only, the bit-mask, in this case, is (0010 0110)2 in a binary number (bit 1, 2, and 5 are set to "1", other bits are set to "0"). Then convert the vale to a bit-mask address by shifting the bit-mask value to left by 2-bits. It will be (00 1001 1000)2 in binary. You can use a bit-mask to indicate which bits are to be modified and if you look in the diagram:
EK-TM4C123GXL LaunchPad
GPIO Ports
The microcontroller on the EK-TM4C123GXL LaunchPad is TM4C123GH6PM. The TM4C123GH6PM GPIO module is comprised of six physical GPIO blocks, each corresponding to an individual GPIO port (Port A, Port B, Port C, Port D, Port E, and Port F).
Figure 1: I/O Port Pins for the TM4C123GH6PM (From http://users.ece.utexas.edu/~valvano/Volume1/E-Book/C6_MicrocontrollerPorts.htm)
Port A ~ Port D have 8-pin I/O on each port; Port E has 6-pins, and Port F has 5-pins.
On the TM4C123G LaunchPad, all inputs of the GPIO are 5V tolerant, except a few GPIOs (PB0, PB1, and PD5). The 5V tolerant feature of Tiva C MCUs comes to aid, allowing us to use legacy external interfaces and devices like sensors, external modules, legacy microcontrollers, etc. without the need for additional logic level translator circuits. Though most pins are 5V tolerant, it doesn't necessarily mean that the logic level is based on the 5V TTL logic level. The logic level voltage limits are still realized with respect to VDD, 3.3V.
On the TM4C123G microcontrollers, the GPIO Ports can be connected to either the Advanced Peripheral Bus (APB) or the Advanced High-performance Bus (AHB). After reset, the GPIO Ports are connected to the legacy APB bus, and through the APB memory aperture. Each GPIO port can be individually configured to use AHB or APB through the "Register 9: GPIO High-Performance Bus Control (GPIOHBCTL), offset 0x06C". The AHB bus provides better back-to-back access performance than the APB bus.
Table 1: GPIO Port's Base Address
APB Bus | AHB Bus | |||
GPIO Port | Base Address | Range | Base Address | Range |
Port A | 0x4000.4000 | 0x4000.4000 ~ 0x4000.4FFF | 0x4005.8000 | 0x4005.8000 ~ 0x4005.8FFF |
Port B | 0x4000.5000 | 0x4000.5000 ~ 0x4000.5FFF | 0x4005.9000 | 0x4005.9000 ~ 0x4005.9FFF |
Port C | 0x4000.6000 | 0x4000.6000 ~ 0x4000.6FFF | 0x4005.A000 | 0x4005.A000 ~ 0x4005.AFFF |
Port D | 0x4000.7000 | 0x4000.7000 ~ 0x4000.7FFF | 0x4005.B000 | 0x4005.B000 ~ 0x4005.BFFF |
Port E | 0x4002.4000 | 0x4002.4000 ~ 0x4002.4FFF | 0x4005.C000 | 0x4005.C000 ~ 0x4005.CFFF |
Port F | 0x4002.5000 | 0x4002.5000 ~ 0x4002.5FFF | 0x4005.D000 | 0x4005.D000 ~ 0x4005.DFFF |
Each GPIO port has 4KB of memory space because each GPIO Port has a large number of special function registers associated with it, and the GPIO Data Register supports bit-specific addressing to allows a single instruction to access from 1-bit to 8-bits data in the memory map.
Registers
The GPIO Ports must be initialized before used. The basic steps to configure the required PORTn pins to GPIO are given below:
- Enabled the clock to the GPIO Port by setting the corresponding bit in the SYSCTL_RCGCGPIO_R register. Then, wait for the GPIO clock ready by check the SYSCTL_PRGPIO register.
- Unlock the port by writing 0x4C4F434B to GPIO_PORTn_LOCK_R register. The step is needed only for PORTC[3:0], PORTD[7], and PORTF[0] on TM4C123G. The only needing unlocking on the TM4C1294 is PORTD[7]. After unlocking the port, the appropriate bits of the GPIO Commit register (GPIO_PORTn_CR_R) need to be set.
- Disable the analog function of the pin in the Analog Mode Select register (GPIO_PORTn_AMSEL_R), because we want to use the pin for digital I/O. If this pin is connected to the ADC or analog comparator, its corresponding bit in GPIO_PORTn_AMSEL_R must be set as 1. If this pin is used as digital I/O, its corresponding bit must be set as 0.
- Clear bits in the port control register (GPIO_PORTn_PCTL_R) to select regular digital function. Each GPIO pin needs 4-bit in its corresponding GPIO_PORTn_PCTL_R register. Not every pin can be configured to every alternative function.
- Clear bits in the Alternate Function Select register (GPIO_PORTn_AFSEL). If an alternate pin is chosen for a bit, then the PMCn field must be programmed in the GPIO_PORTn_PCTL_R register for the specific peripheral required.
- Set the direction of the GPIO port pins by programming the GPIO_PORTn_DIR_R register. A bit in GPIO_PORTn_DIR_R set to 0 means input and 1 means output.
- Program each pad in the port to have either pull-up, pull-down, or open-drain functionality through the GPIO_PORTn_PUR_R, GPIO_PORTn_PDR_R, GPIO_PORTn_ODR_R register.
- To enable GPIO pins as digital I/Os, set the appropriate DEN bit in the Digital Enable register (GPIO_PORTn_DEN_R).
The first step must be turning on the clock, and other steps can occur in any order.
After a RESET, the default state is to disable the analog function and disable the alternate function. Therefore, steps 3, 4, and 6 can be skipped.
Address | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Name |
$400F.E108 | -- | -- | GPIOF | GPIOE | GPIOD | GPIOC | GPIOB | GPIOA | SYSCTL_RCGCGPIO_R |
PORTn BaseAddr + $3FC | DATA | DATA | DATA | DATA | DATA | DATA | DATA | DATA | GPIO_PORTn_DATA_R |
PORTn BaseAddr + $400 | DIR | DIR | DIR | DIR | DIR | DIR | DIR | DIR | GPIO_PORTn_DIR_R |
PORTn BaseAddr + $420 | SEL | SEL | SEL | SEL | SEL | SEL | SEL | SEL | GPIO_PORTn_AFSEL_R |
PORTn BaseAddr + $50C | ODE | ODE | ODE | ODE | ODE | ODE | ODE | ODE | GPIO_PORTn_ODR_R![]() |
PORTn BaseAddr + $510 | PUE | PUE | PUE | PUE | PUE | PUE | PUE | PUE | GPIO_PORTn_PUR_R |
PORTn BaseAddr + $514 | PDE | PDE | PDE | PDE | PDE | PDE | PDE | PDE | GPIO_PORTn_PDR_R |
PORTn BaseAddr + $51C | DEN | DEN | DEN | DEN | DEN | DEN | DEN | DEN | GPIO_PORTn_DEN_R |
PORTn BaseAddr + $524 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | GPIO_PORTn_CR_R |
PORTn BaseAddr + $528 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | GPIO_PORTn_AMSEL_R |
31-28 | 27-24 | 23-20 | 19-16 | 15-12 | 11-8 | 7-4 | 3-0 | ||
PORTn BaseAddr + $52C | PMC7 | PMC6 | PMC5 | PMC4 | PMC3 | PMC2 | PMC1 | PMC0 | GPIO_PORTn_PCTL_R |
PORTC BaseAddr + $520 | LOCK (write 0x4C4F434B to unlock, other locks) (reads 1 if locked, 0 if unlocked) | GPIO_PORTC_LOCK_R | |||||||
PORTC BaseAddr + $520 | LOCK (write 0x4C4F434B to unlock, other locks) (reads 1 if locked, 0 if unlocked) | GPIO_PORTD_LOCK_R | |||||||
PORTC BaseAddr + $520 | LOCK (write 0x4C4F434B to unlock, other locks) (reads 1 if locked, 0 if unlocked) | GPIO_PORTF_LOCK_R |
* PORTn ➤ PORTA, PORTB, PORTC, PORTD, PORTE and PORTF
On-board I/O
- Two USB connectors on the board.
- The top one is an integrated In-Circuit Debug Interface (ICDI), which allows programming and debugging of the onboard TM4C microcontroller.
- the left USB connector allows you to develop USB applications (device or host).
- Switch-selectable power sources
Select one of the two power sources
- Left-Hand DEVICE Position: powered by USB device port
- Right-Hand DEBUG Position: powered by USB debug (ICDI) port
- Reset button
- Two user switches (SW1 and SW2)
- RGB User LED
- Stackable 40-pin BoosterPack XL interface
Sample Firmware Code in Assembly
Launch the Keil μVision5 on your computer and then create a new project. Copy-and-pate the following source code into your main.s
Please download the definition ZIP file and extract it into the same project folder: TM4C123GH6PM.zip
The following source code is to turn on the onboard of switches and RGB LEDs on PORTF
;This is the first ARM Assembly language program you see in the lab ;This program template was created by Airs Lin @ 2017 California State University of Los Angeles. ;When you write your program, you could have your info at the top document block ;For Example: Your Name, Student Number, what the program is for, and what it does etc. INCLUDE TM4C123GH6PM.s ; Constant Variable Here STACK_ADDR_123G EQU 0x20008000 LED_R EQU 2_00000010 LED_B EQU 2_00000100 LED_G EQU 2_00001000 SW1 EQU 2_00010000 SW2 EQU 2_00000001 THUMB ; Vector Table Mapped to Address 0 at Reset ; Linker requires __Vectors to be exported AREA RESET, DATA, READONLY EXPORT __Vectors __Vectors DCD STACK_ADDR_123G ; stack pointer value when stack is empty DCD Reset_Handler ; reset vector ALIGN ; The program ; Linker requires Reset_Handler AREA |.text|, CODE, READONLY ENTRY ; mark first instruction to execute EXPORT Reset_Handler Reset_Handler ; This subroutine grants access to ; floating point coprocessor. ; It is called by the startup code. LDR R0, =0xE000ED88 ; Enable CP10,CP11 LDR R1,[R0] ORR R1,R1,#0x20 STR R1,[R0] DSB ; wait for store to complete ISB ;reset pipeline now the FPU is enabled ;===================== ; 1. Turn on Port F clock in SYSCTL_RCGCGPIO_R, then chcek SYSCTL_PRGPIO_R ready flag ; enable clock to GPIOF at clock gating register LDR R0, =SYSCTL_RCGCGPIO_R ; RCGC reg. addr. LDR R1, [R0] ORR R1, #(GPIO_PORTF) STR R1, [R0] LDR R0, =SYSCTL_PRGPIO_R WAIT4GPIO LDR R1, [R0] TST R1, #(GPIO_PORTF) BEQ WAIT4GPIO ; 2. Unlock PF0 and/or PD7 for TM4C123G board ; unlock PortF LDR R0, =PORT_UNLOCK_CODE LDR R1, [R0] LDR R0, =GPIO_PORTF_LOCK_R STR R1, [R0] NOP NOP LDR R0, =GPIO_PORTF_CR_R ; Enable Commit for PF0 LDR R1, [R0] ORR R1, #0x01 STR R1, [R0] ; 3. Clear AMSEL to disable analog LDR R0, =GPIO_PORTF_AMSEL_R MOV R1, #0x00 STR R1, [R0] ; 4. Clear PCTL to select GPIO LDR R0, =GPIO_PORTF_PCTL_R MOV R1, #0x0000 STR R1, [R0] ; 5. Clear AFSEL bits to 0 to select regular I/O LDR R0, = GPIO_PORTF_AFSEL_R MOV R1, #0x00 STR R1, [R0] ; 6. Set DIR to 0 for input, 1 for output ; set PORTF pin3-1 as output pins LDR R0, =GPIO_PORTF_DIR_R MOV R1, #0x0E ; pin 1, 2 and 3 are output STR R1, [R0] ; 7. Set PUR bits to 1 to enable internal pull-up LDR R0, =GPIO_PORTF_PUR_R MOV R1, #0x11 ; pin 0 and 4 connect with switch STR R1, [R0] ; 8 Set DEN bits to 1 to enable data pins LDR R0, =GPIO_PORTF_DEN_R LDR R1, [R0] ORR R1, #0x1F STR R1, [R0] ;;;;;;;;;; Your Main Code Starts from the next line ;;;;;;;;;;;; DeadLoop B DeadLoop ; Infinite loop to end program ; The constant variable area ; The value will be stored on ROM segment AREA ConstantVariables, DATA, READONLY PORT_UNLOCK_CODE DCD 0x4C4F434B ; The variables area ; The variables will be assigned to RAM area AREA Variables, DATA, READWRITE END ; End of the program
Keic C Sample Firmware Code
The following source code is to turn on the onboard RGB LEDs and switch button (SW2) on PORTF
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include "TM4C123GH6PM.h" void Setup_GPIO(); void DelayMs(int s); int main(void) { Setup_GPIO(); while(1){ if ( GPIOF->DATA & 0x01 ){ GPIOF->DATA = 0x02; DelayMs(1000); GPIOF->DATA = 0x04; DelayMs(1000); GPIOF->DATA = 0x08; DelayMs(1000); } else { GPIOF->DATA = 0x0E; DelayMs(1000); GPIOF->DATA = 0x00; DelayMs(1000); } } } void Setup_GPIO() { // GPIO Initialization and Configuration // 1. Enable Clock to the GPIO Modules (SYSCTL->RCGCGPIO) SYSCTL->RCGCGPIO |= 0x20; // allow time for clock to stabilize (SYSCTL->PRGPIO) while((SYSCTL->PRGPIO & (0x20) ) != (0x20) ){}; // 2. Unlock GPIO only PD7, PF0 on TM4C123G; PD7, PE7 on TM4C1294 (GPIO->LOCK and GPIO->CR) GPIOF->LOCK = 0x4C4F434B; GPIOF->CR |= 0x01; // 3. Set Analog Mode Select bits for each Port (GPIO->AMSEL 0=digital, 1=analog) GPIOF->AMSEL = 0x00; // 4. Set Port Control Register for each Port (GPIO->PCTL, check the PCTL table) GPIOF->PCTL = 0x00; // 5. Set Alternate Function Select bits for each Port (GPIO->AFSEL 0=regular I/O, 1=PCTL peripheral) GPIOF->AFSEL = 0x00; // 6. Set Output pins for each Port (Direction of the Pins: GPIO->DIR 0=input, 1=output) GPIOF->DIR = 0x0E; // PF3,PF2,PF1 for Output // 7. Set PUR bits for internal pull-up, PDR for pull-down reg, ODR for open drain (0: disable, 1=enable) GPIOF->PUR = 0x01; // 8. Set Digital ENable register on all GPIO pins (GPIO->DEN 0=disable, 1=enable) GPIOF->DEN = 0x0F; // Enable all digital pins on PortF (PF3,PF2,PF1,PF0) } void DelayMs(int s) { volatile int i, j; for (i = 0; i < s; i++) for (j = 0; j < 3180; j++) {}; }
EK-TM4C1294XL LaunchPad
GPIO Ports
The microcontroller on the EK-TM4C1294XL LaunchPad is TM4C1294NCPDT. The TM4C1294NCPDT GPIO module is comprised of fifteen physical GPIO blocks, each corresponding to an individual GPIO port (Port A, Port B, Port C, Port D, Port E, Port F, PORTG, PORTH, PORTJ, PORTK, PORTL, PORTM, PORTN, PORTP, and PORTQ).
On the TM4C1294 microcontroller, the Advanced High-Performance Bus (AHB) is now the default connection. The movement from APB to AHB reduces the clock latency so you would be getting a better performance for direct GPIO. The base address for each GPIO Ports as shown in Table 2.
Table 2: GPIO Port's Base Address
APB | AHB Bus | |||
GPIO Port | Base Address | Range | Base Address | Range |
Port A | 0x4005.8000 | 0x4005.8000 ~ 0x4005.8FFF | ||
Port B | 0x4005.9000 | 0x4005.9000 ~ 0x4005.9FFF | ||
Port C | 0x4005.A000 | 0x4005.A000 ~ 0x4005.AFFF | ||
Port D | 0x4005.B000 | 0x4005.B000 ~ 0x4005.BFFF | ||
Port E | 0x4005.C000 | 0x4005.C000 ~ 0x4005.CFFF | ||
Port F | 0x4005.D000 | 0x4005.D000 ~ 0x4005.DFFF | ||
Port G | 0x4005.E000 | 0x4005.E000 ~ 0x4005.EFFF | ||
Port H | 0x4005.F000 | 0x4005.F000 ~ 0x4005.FFFF | ||
Port J | 0x4006.0000 | 0x4006.0000 ~ 0x4006.0FFF | ||
Port K | 0x4006.1000 |
0x4006.1000 ~ 0x4006.1FFF | ||
Port L | 0x4006.2000 | 0x4006.2000 ~ 0x4006.2FFF | ||
Port M | 0x4006.3000 | 0x4006.3000 ~ 0x4006.3FFF | ||
Port N | 0x4006.4000 | 0x4006.4000 ~ 0x4006.4FFF | ||
Port P | 0x4006.5000 | 0x4006.5000 ~ 0x4006.5FFF | ||
Port Q | 0x4006.6000 | 0x4006,6000 ~ 0x4006.6FFF |
Registers
The GPIO Ports must be initialized before used. The basic steps to configure the required PORTn pins to GPIO are given below:
- Enabled the clock to the GPIO Port by setting the corresponding bit in the SYSCTL_RCGCGPIO_R register. Then, wait for the GPIO clock to ready by check the SYSCTL_PRGPIO register
- Unlock the port by writing 0x4C4F434B to GPIO_PORTn_AHB_LOCK_R register. The step is needed only for PORTD[7], and PORTF[0] on TM4C123G. The only needing unlocking on the TM4C1294 is PORTD[7]. After unlocking the port, the appropriate bits of the GPIO Commit register (GPIO_PORTn_AHB_CR_R) need to be set.
- Disable the analog function of the pin in the Analog Mode Select register (GPIO_PORTn_AHB_AMSEL_R), because we want to use the pin for digital I/O. If this pin is connected to the ADC or analog comparator, its corresponding bit in GPIO_PORTn_AHB_AMSEL_R must be set as 1. If this pin is used as digital I/O, its corresponding bit must be set as 0.
- Clear bits in the port control register (GPIO_PORTn_AHB_PCTL_R) to select regular digital function. Each GPIO pin needs 4-bit in its corresponding GPIO_PORTn_AHB_PCTL_R register. Not every pin can be configured to every alternative function.
- Clear bits in the Alternate Function Select register (GPIO_PORTn_AHB_AFSEL_R). If an alternate pin is chosen for a bit, then the PMCn field must be programmed in the GPIO_PORTn_AHB_PCTL_R register for the specific peripheral required.
- Set the direction of the GPIO port pins by programming the GPIO_PORTn_AHB_DIR_R register. A bit in GPIO_PORTn_AHB_DIR_R set to 0 means input and 1 means output.
- Program each pad in the port to have either pull-up, pull-down, or open-drain functionality through the GPIO_PORTn_AHB_PUR_R, GPIO_PORTn_AHB_PDR_R, GPIO_PORTn_AHB_ODR_R register.
- To enable GPIO pins as digital I/Os, set the appropriate DEN bit in the Digital Enable register (GPIO_PORTn_AHB_DEN_R).
The first step must be turning on the clock, and other steps can occur in any order.
After a RESET, the default state is to disable the analog function and disable the alternate function. Therefore, steps 3, 4, and 6 can be skipped.
Address | bit-Field | Name | |||||||
$400F.E108 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | SYSCTL_RCGCGPIO_R |
--- | GPIOQ | GPIOP | GPION | GPIOM | GPIOL | GPIOK | GPIOJ | ||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
GPIOH | GPIOG | GPIOF | GPIOE | GPIOD | GPIOC | GPIOB | GPIOA | ||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
PORTn BaseAddr + $3FC | DATA | DATA | DATA | DATA | DATA | DATA | DATA | DATA | GPIO_PORTn_AHB_DATA_R |
PORTn BaseAddr + $400 | DIR | DIR | DIR | DIR | DIR | DIR | DIR | DIR | GPIO_PORTn_AHB_DIR_R |
PORTn BaseAddr + $420 | SEL | SEL | SEL | SEL | SEL | SEL | SEL | SEL | GPIO_PORTn_AHB_AFSEL_R |
PORTn BaseAddr + $50C | ODE | ODE | ODE | ODE | ODE | ODE | ODE | ODE | GPIO_PORTn_AHB_ODR_R |
PORTn BaseAddr + $510 | PUE | PUE | PUE | PUE | PUE | PUE | PUE | PUE | GPIO_PORTn_AHB_PUR_R |
PORTn BaseAddr + $514 | PDE | PDE | PDE | PDE | PDE | PDE | PDE | PDE | GPIO_PORTn_AHB_PDR_R |
PORTn BaseAddr + $51C | DEN | DEN | DEN | DEN | DEN | DEN | DEN | DEN | GPIO_PORTn_AHB_DEN_R |
PORTn BaseAddr + $524 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | GPIO_PORTn_AHB_CR_R |
PORTn BaseAddr + $528 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | GPIO_PORTn_AHB_AMSEL_R |
15-14 | 13-12 | 11-10 | 9-8 | 7-6 | 5-4 | 3-2 | 1-0 | ||
PORTn BaseAddr + $FC4 | EDM7 | EDM6 | EDM5 | EDM4 | EDM3 | EDM2 | EDM1 | EDM0 | GPIO_PORTn_AHB_PC_R |
31-28 | 27-24 | 23-20 | 19-16 | 15-12 | 11-8 | 7-4 | 3-0 | ||
PORTn BaseAddr + $52C | PMC7 | PMC6 | PMC5 | PMC4 | PMC3 | PMC2 | PMC1 | PMC0 | GPIO_PORTn_AHB_PCTL_R |
PORTD BaseAddr + $520 | LOCK (write 0x4C4F434B to unlock, other locks) (reads 1 if locked, 0 if unlocked) | GPIO_PORTD_AHB_LOCK_R |
* PORTn ➤ PORTA, PORTB, PORTC, PORTD, PORTE, PORTF, PORTG, PORTH, PORTJ, PORTK, PORTL, PORTM, PORTN, PORTP, and PORTQ
On-board I/O
- Two USB connectors
- Two independent BoosterPack XL standard connectors
- 10/100Mbps Ethernet Port
- 2 user buttons
- 4 user LEDs
- 1 independent hibernate wake switch
- 1 independent reset switch
- Jumper for selecting a power source
- JTAG port for debug port
Sample Firmware Code in Assembly
Launch the Keil μVision5 on your computer and then create a new project. Copy-and-pate the following source code into your main.s
Please download the definition ZIP file and extract it into the same project folder: TM4C1294NCPDTI.zip
The following source code is to turn on the onboard of switches and LEDs on PORTF, PORTN, and PORTJ
;This is the first ARM Assembly language program you see in the lab ;This program template was created by Airs Lin @ 2017 California State University of Los Angeles. ;When you write your program, you could have your info at the top document block ;For Example: Your Name, Student Number, what the program is for, and what it does etc. INCLUDE TM4C1294NCPDT.s ; Constant Variable Here STACK_ADDR_123G EQU 0x20008000 LED1_N EQU 2_00000010 LED2_N EQU 2_00000001 LED3_F EQU 2_00010000 LED4_F EQU 2_00000001 SW1_J EQU 2_00000001 SW2_J EQU 2_00000010 THUMB ; Vector Table Mapped to Address 0 at Reset ; Linker requires __Vectors to be exported AREA RESET, DATA, READONLY EXPORT __Vectors __Vectors DCD STACK_ADDR_123G ; stack pointer value when stack is empty DCD Reset_Handler ; reset vector ALIGN ; The program ; Linker requires Reset_Handler AREA |.text|, CODE, READONLY ENTRY ; mark first instruction to execute EXPORT Reset_Handler Reset_Handler ; This subroutine grants access to ; floating point coprocessor. ; It is called by the startup code. LDR R0, =0xE000ED88 ; Enable CP10,CP11 LDR R1,[R0] ORR R1,R1,#0x20 STR R1,[R0] DSB ; wait for store to complete ISB ;reset pipeline now the FPU is enabled ;===================== ; 1. Turn on Port F clock in SYSCTL_RCGCGPIO_R, tehn check SYSCTL_PRGPIO ; enable clock to GPIOF at clock gating register LDR R0, =SYSCTL_RCGCGPIO_R ; RCGC reg. addr. MOV R1, #(GPIO_PORTF :OR: GPIO_PORTJ :OR: GPIO_PORTN) STR R1, [R0] LDR R0, =SYSCTL_PRGPIO_R Wait4GPIO LDR R1, [R0] TST R1, #(GPIO_PORTF :OR: GPIO_PORTJ :OR: GPIO_PORTN) BEQ Wait4GPIO ; 2. Unlock PD7 only ; 3. Clear AMSEL to disable analog MOV R1, #0x00 LDR R0, =GPIO_PORTF_AHB_AMSEL_R STR R1, [R0] LDR R0, =GPIO_PORTJ_AHB_AMSEL_R STR R1, [R0] LDR R0, =GPIO_PORTN_AHB_AMSEL_R STR R1, [R0] ; 4. Clear PCTL to select GPIO MOV R1, #0x0000 LDR R0, =GPIO_PORTF_AHB_PCTL_R STR R1, [R0] LDR R0, =GPIO_PORTJ_AHB_PCTL_R STR R1, [R0] LDR R0, =GPIO_PORTN_AHB_PCTL_R STR R1, [R0] ; 5. Clear AFSEL bits to 0 to select regular I/O MOV R1, #0x00 LDR R0, =GPIO_PORTF_AHB_AFSEL_R STR R1, [R0] LDR R0, =GPIO_PORTN_AHB_AFSEL_R STR R1, [R0] LDR R0, =GPIO_PORTJ_AHB_AFSEL_R STR R1, [R0] ; 6. Set DIR to 0 for input, 1 for output LDR R0, =GPIO_PORTF_AHB_DIR_R MOV R1, #(BIT4 :OR: BIT0) ; PF4 & PF0 to LED STR R1, [R0] LDR R0, =GPIO_PORTN_AHB_DIR_R MOV R1, #(BIT1 :OR: BIT0) ; PN1 & PN0 to LED STR R1, [R0] LDR R0, =GPIO_PORTJ_AHB_DIR_R MOV R1, #0x00 ; PJ1 & PJ0 to Switch STR R1, [R0] ; 7. Set PUR bits to 1 to enable internal pull-up LDR R0, =GPIO_PORTJ_AHB_PUR_R MOV R1, #(BIT1 :OR: BIT0) STR R1, [R0] ; 8 Set DEN bits to 1 to enable data pins LDR R0, =GPIO_PORTF_AHB_DEN_R LDR R1, [R0] ORR R1, #0x11 STR R1, [R0] LDR R0, =GPIO_PORTN_AHB_DEN_R LDR R1, [R0] ORR R1, #0x03 STR R1, [R0] LDR R0, =GPIO_PORTJ_AHB_DEN_R LDR R1, [R0] ORR R1, #0x03 STR R1, [R0] ;;;;;;;;;; Your Main Code Starts from the next line ;;;;;;;;;;;; DeadLoop B DeadLoop ; Infinite loop to end program ; The constant variable area ; The value will be stored on ROM segment AREA ConstantVariables, DATA, READONLY PORT_UNLOCK_CODE DCD 0x4C4F434B ; The variables area ; The variables will be assigned to RAM area AREA Variables, DATA, READWRITE END ; End of the program
Sample Firmware Code for Keil C
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include "TM4C1294NCPDT.h" void Setup_GPIO(); void DelayMs(int s); int main(void) { Setup_GPIO(); while(1){ GPIOF_AHB->DATA = 0x01; DelayMs(1000); GPIOF_AHB->DATA = 0x10; DelayMs(1000); GPIOF_AHB->DATA = 0x00; GPION->DATA = 0x01; DelayMs(1000); GPION->DATA = 0x02; DelayMs(1000); GPION->DATA = 0x00; } } void Setup_GPIO() { // GPIO Initialization and Configuration // 1. Enable Clock to the GPIO Modules (SYSCTL->RCGCGPIO) SYSCTL->RCGCGPIO |= 0x1020; // allow time for clock to stabilize (SYSCTL->PRGPIO) while((SYSCTL->PRGPIO & (0x1020) ) != (0x1020) ){}; // 2. Unlock GPIO only PD7, PF0 on TM4C123G; PD7, PE7 on TM4C1294 (GPIO->LOCK and GPIO->CR) // 3. Set Analog Mode Select bits for each Port (GPIO->AMSEL 0=digital, 1=analog) GPIOF_AHB->AMSEL = 0x00; GPION->AMSEL = 0x00; // 4. Set Port Control Register for each Port (GPIO->PCTL, check the PCTL table) GPIOF_AHB->PCTL = 0x00; GPION->PCTL = 0x00; // 5. Set Alternate Function Select bits for each Port (GPIO->AFSEL 0=regular I/O, 1=PCTL peripheral) GPIOF_AHB->AFSEL = 0x00; GPION->AFSEL = 0x00; // 6. Set Output pins for each Port (Direction of the Pins: GPIO->DIR 0=input, 1=output) GPIOF_AHB->DIR = 0x11; // PF4,PF0 for Output GPION->DIR = 0x03; // 7. Set PUR bits for internal pull-up, PDR for pull-down reg, ODR for open drain (0: disable, 1=enable) // 8. Set Digital ENable register on all GPIO pins (GPIO->DEN 0=disable, 1=enable) GPIOF_AHB->DEN = 0x11; // Enable all digital pins on PortF (PF4, PF0) GPION->DEN = 0x03; // Enable all digital pins on PortN (PN1, PN0) } void DelayMs(int s) { volatile int i, j; for (i = 0; i < s; i++) for (j = 0; j < 3180; j++){}; }