lab 1 familiarization and digital i/o - eth z · 2019-09-09 · 1 s32k144 d0 pin name s32k144 pin...
TRANSCRIPT
1
1
Lab 1 Familiarization and Digital I/O
2
LEDs and DIPs for GPIO
S32K and interface board
Haptic Wheel
Lab Set-up
3
3
Lab 1• Lab set-up:
– Input pins are connected to DIP switches– Output pins are connected to LEDs
• Writing to a memory mapped register associated with an output pin lights an LED
• Reading from a memory mapped register associated with an input pin indicates whether the DIP is “on” or “off”
• You will write a simple program (lab1.c) to add two 4-bit numbers specified on the DIP switches and write the result to the LED display
• You will then modify your program to use serial interface and keyboard instead of DIP switches
• S32K144 Reference Manual (very large, on website)– Chapter 12, Port Control and Interrupts (PORT)– Chapter 13, General Purpose Input/Output (GPIO)
4
4
Pins, Ports, and Pads
• S32K144 has 100 pins (there are
also versions with more or less
pins)
• Pins are the physical connection
from the CPU to the outside world
• Any particular pin may be able to
connect to multiple devices:
Memory, sensors, ADC, etc.
• The pins are organized into 5
different groups called ports• Different I/O circuitry required
depending on the pin function
• The I/O circuitry which enables the
pin is called the pad
4.3 Pad descriptionFollowing figure shows the basic representation of a GPIO Pad.
obe
do
pue
pus
ibe
ind
Pull logic
InputReceiver
Output Driver
Pad
Figure 4-2. GPIO pad representation
Table 4-1. Pad Signal description
Signal name Direction Descriprtion
pad I/O I/O to external world
do I Data coming from the core into the pad
obe I Enable output driver
pue I 0: Disable internal pullup or pulldown resistor 1: Enable internal pullup orpulldown resistor
pus I 0: Enable internal pulldown resistor if pue is set 1: Enable internal pullupresistor if pue is set
ibe I Enable input receiver
ind O Data coming out of the pad into the core
Pad description
S32K1xx Series Reference Manual, Rev. 9, 09/2018
84 NXP Semiconductors
5Port Control and Interrupt Module
• Port Control and Interrupt Module (PORT), on the S32K144 is used to manage the hardware “pins” that are used for input and output.
6PORT Module
• The PORT Module contains Pin Configuration Registers (PCRs) that are used to specify the purpose of a pin.
• PCR n in Port x is referred to as PTxn and is located at an offset from the base address for that port. See Section 12.1.2 of the S32K reference manual.
• For port base addresses, see S32K1xx memory map found in the spreadsheet S32K1xx_Memory_Map.xlsx
• Each port has additional registers we won’t be using.
7Memory Map
• See the spreadsheet S32K1xx_Memory_Map.xlsx • Base address of all memory modules and peripheral devices• Subsequent references to register locations are as offsets from the
base address (start address) given in the memory map. • Will need some of these in Lab 1
LED
DIP ON ON
16D15
15D14
14D13
13D12
12D11
11D10
10D9
9D8
8D7
7D6
6D5
5D4
4D3
3D2
2 D1
1D0S32K144
pin name
S32K144pin name
8 7 6 5 4 3 2 1 16 15 14 13 12 11 10 9E13 E12 E11 E10 E9 E8 E7 E6 D17 E3 E2 E1 E0 E16 E15 E14
ON
8
8
Lab 1 GPIO
• Pin numbers are not labeled on the interface board. • Pin numbers E6-E16, E1-E3, D17 are connected to DIP switches 1-16. • Pin numbers D0-D15 are connected to LEDs 1-16.
Pin 15, Port D
9
Finding the PCR Address8 bits
Port D Base Address = 0x4004C000 = Pin D0 PCR address
32 bit PCRPin D0
32 bit PCRPin D1
Pin D1 PCR address = base + 4*pin number (hex)
Memory Map:
• Pin Configuration register (PCR).• One set of PCRs for the pins in each port.• PCR register bitfields – Section 12.6.1 • MUX register determines purpose of pin: set MUX to 0b001 for GPIO.• Other bitfields set various electrical properties – leave at reset values.
10
Lab 1 PCR for GPIO
GPIO Registers11
• Once a pin is configured for GPIO, additional properties are specified by GPIO registers (Section 13.3.1.1)
• One set of GPIO registers for each port (Table 13.1)
What are the base addresses for GPIO?(see the memory map)GPIOA: 0x400FF000GPIOB: 0x400FF040GPIOC: 0x400FF080etc.
GPIO Registers12
• Each GPIO register has one bit for each pin associated with the port- some bits in the register not used
• Port Data Direction Register (PDDR)- is the pin used for input or output?
• Port Data Output Register (PDOR)- if output, sets the value on the pin (0 or 1)
• Port Data Input Register (PDIR)- if input, reads the value of the pin (0 or 1)
Example: Port Data Direction Register (PDDR)
13
• D17 is an input pin• GPIOD base address is 0x400FF0C0• PDDR offset is 0x14• Write “0” to bit 17 GPIOD PDDR at 0x400FF0D4
Example: Port Data Output Register (PDDR)
14
• Light LED D0• GPIOD base address is 0x400FF0C0• PDOR offset is 0• Write “1” to bit 0 GPIOD PDOR at 0x400FF0C0
Lab #1 Part 1• In part 1 of lab #1, you will write a header file to
– Define base addresses for Ports D and E that contain the PCRs you will configuring for GPIO
– Define the base address of the GPIO module– Define offsets from the GPIO base address to
reach the GPIO registers for Ports D and E– Create a struct to access all the GPIO registers for
a given port.• Write a program using your header file to add two 4-
bit numbers specified on dip switches 1–4 and 5–8 (pins E6–E9 and E10–E13) and then display the results on LEDs 1-5 (pins D0–D4).
15
16
#define BASE_PORTD /* fill in */
#define BASE_PORTE /* fill in */
#define BASE_GPIO /* fill in */
#define GPIOD_OFFSET /* fill in */
#define GPIOE_OFFSET /* fill in */
typedef struct {
/* fill in using the information on GPIO registers in Section 13.3.1.1 */
} GPIO_mem;
Create the file mylab1header.h
Name your struct
Base addresses and offsets: SeeMemory map and Chapters 12 and 13
For example:volatile uint32_t PDOR;volatile uint32_t PSOR;…volatile uint32_t PDIR;
Create a struct containing all the GPIO registers
17
#include "eecs461.h"
#include <stdint.h>
#define SECTION 1
#if SECTION == 1
#include "mylab1header.h”
void section1(){
volatile uint32_t * const portD_PCR = (uint32_t *)(BASE_PORTD);
volatile uint32_t * const portE_PCR = (uint32_t *)(BASE_PORTE);
GPIO_mem * const gpioD = (GPIO_mem *)(BASE_GPIO + GPIOD_OFFSET);
GPIO_mem * const gpioE = (GPIO_mem *)(BASE_GPIO + GPIOE_OFFSET);
uint16_t sum, value1, value2;
uint32_t regReadVal;
int index;
File lab1.c: Read and Write GPIO using your header file
Set up pointers to Ports and GPIO registers
18
/* Configure the LED pins */
for(index = 0; index < 16; index++){
/* Configure pin mux to gpio */
portD_PCR[index] = 0b001 << 8;
/* Set the direction to output */
gpioD->PDDR |= 0b1 << index;
}
/* Configure the DIP pins */
for(index = 6; index < 14; index++){
/* Configure pin mux to gpio */
portE_PCR[index] = 0b001 << 8;
/* Set the direction to input */
gpioE->PDDR &= ~(1 << index);
}
File lab1.c: Read and Write GPIO using your header file (continued)
Set bit 8 (MUX field) = 1 for each Port D PCR
Set data direction bits for output
19
while(1){
value1 = 0;
value2 = 0;
sum = 0;
/* Read the GPIOE input register, extract the two 4 bit numbers
set on dipswitches 1-4 and 5-8 */
/* Calculate the sum and write to the GPIOD output register
to display the results on LEDs1-5. */
}
}
Read and Write GPIO (continued)
20
20
S32K144 Register Definitions
** ###################################################################** Processor: S32K144_100** Reference manual: S32K14XRM Rev. 2, 02/2017** Version: rev. 2.8, 2017-03-27** Build: b170328**** Abstract:** Peripheral Access Layer for S32K144**** Copyright (c) 1997 - 2016 Freescale Semiconductor, Inc.** Copyright 2016-2017 NXP
• NXP/S32K144.h has registers, bit field definitions
• Don’t have to write your own header (except lab #1 part 1)
21
21
S32K144.h Register Definitions: Port Struct/** PORT - Size of Registers Arrays */#define PORT_PCR_COUNT 32u
/** PORT - Register Layout Typedef */typedef struct {__IO uint32_t PCR[PORT_PCR_COUNT] /* Pin Control Register n, array offset: 0x0,
array step: 0x4 */__O uint32_t GPCLR; /* Global Pin Control Low Register, offset: 0x80 */__O uint32_t GPCHR; /* Global Pin Control High Register, offset: 0x84 */
uint8_t RESERVED_0[24];__IO uint32_t ISFR; /**< Interrupt Status Flag Register, offset: 0xA0 */
uint8_t RESERVED_1[28];__IO uint32_t DFER; /* Digital Filter Enable Register, offset: 0xC0 */__IO uint32_t DFCR; /* Digital Filter Clock Register, offset: 0xC4 */__IO uint32_t DFWR; /* Digital Filter Width Register, offset: 0xC8 */
} PORT_Type, *PORT_MemMapPtr;
Struct created for array of PCRs
Port Addresses and Pointers are Defined22
/* PORT - Peripheral instance base addresses *//** Peripheral PORTA base address */#define PORTA_BASE (0x40049000u)/** Peripheral PORTA base pointer */#define PORTA ((PORT_Type *)PORTA_BASE)/** Peripheral PORTB base address */#define PORTB_BASE (0x4004A000u)/** Peripheral PORTB base pointer */#define PORTB ((PORT_Type *)PORTB_BASE)/** Peripheral PORTC base address */#define PORTC_BASE (0x4004B000u)/** Peripheral PORTC base pointer */#define PORTC ((PORT_Type *)PORTC_BASE)/** Peripheral PORTD base address */#define PORTD_BASE (0x4004C000u)/** Peripheral PORTD base pointer */#define PORTD ((PORT_Type *)PORTD_BASE)/** Peripheral PORTE base address */#define PORTE_BASE (0x4004D000u)/** Peripheral PORTE base pointer */#define PORTE ((PORT_Type *)PORTE_BASE)/** Array initializer of PORT peripheral base addresses */#define PORT_BASE_ADDRS { PORTA_BASE, PORTB_BASE, PORTC_BASE, PORTD_BASE, PORTE_BASE }
23
23
S32K144.h Register Definitions: GPIO Struct
/** GPIO - Size of Registers Arrays */
/** GPIO - Register Layout Typedef */typedef struct {__IO uint32_t PDOR; /**< Port Data Output Register, offset: 0x0 */__O uint32_t PSOR; /**< Port Set Output Register, offset: 0x4 */__O uint32_t PCOR; /**< Port Clear Output Register, offset: 0x8 */__O uint32_t PTOR; /**< Port Toggle Output Register, offset: 0xC */__I uint32_t PDIR; /**< Port Data Input Register, offset: 0x10 */__IO uint32_t PDDR; /**< Port Data Direction Register, offset: 0x14 */__IO uint32_t PIDR; /**< Port Input Disable Register, offset: 0x18 */
} GPIO_Type, *GPIO_MemMapPtr;
GPIO Addresses and Pointers are Defined
24
/* GPIO - Peripheral instance base addresses *//** Peripheral PTA base address */#define PTA_BASE (0x400FF000u)/** Peripheral PTA base pointer */#define PTA ((GPIO_Type *)PTA_BASE)/** Peripheral PTB base address */#define PTB_BASE (0x400FF040u)/** Peripheral PTB base pointer */#define PTB ((GPIO_Type *)PTB_BASE)/** Peripheral PTC base address */#define PTC_BASE (0x400FF080u)/** Peripheral PTC base pointer */#define PTC ((GPIO_Type *)PTC_BASE)/** Peripheral PTD base address */#define PTD_BASE (0x400FF0C0u)/** Peripheral PTD base pointer */#define PTD ((GPIO_Type *)PTD_BASE)/** Peripheral PTE base address */#define PTE_BASE (0x400FF100u)/** Peripheral PTE base pointer */#define PTE ((GPIO_Type *)PTE_BASE)/** Array initializer of GPIO peripheral base addresses */#define GPIO_BASE_ADDRS { PTA_BASE, PTB_BASE, PTC_BASE, PTD_BASE, PTE_BASE }/** Array initializer of GPIO peripheral base pointers */#define GPIO_BASE_PTRS { PTA, PTB, PTC, PTD, PTE }
25
25
S32K144.h Macros
• The NXP header file S32K144.h uses the #define command to create many variables and functions used with the configuration registers.
• Example: consider the MUX bitfield of the PCR: bits 8-10 of the register
#define PORT_PCR_MUX_MASK 0x700u#define PORT_PCR_MUX_SHIFT 8u#define PORT_PCR_MUX_WIDTH 3u#define PORT_PCR_MUX(x) (((uint32_t)(((uint32_t)(x))<<PORT_PCR_MUX_SHIFT))&PORT_PCR_MUX_MASK)
– PORT_PCR_MUX_MASK enables access to the bits in the MUX bitfield.– PORT_PCR_MUX_SHIFT number of bits to shift to get to the MUX– PORT_PCR_MUX_WIDTH size of the MUX bitfield– PORT_PCR_MUX(x) sets the MUX bitfield to a desired value (0b001 for GPIO)
• Similar variables and functions are defined in S32K144.h for all the registers we will work with.
Lab #1 Part 2
• In the second part of lab #1 you will use the NXP provided header file
• Use the register definitions and structures from the NXP file to write general purpose functions to initialize the GPIO pins for input or output, read from those pins initialized for input, and write to those pins initialized for output.
• You will be given a template file gpio_template.c
26
gpio_template.c (snippet)27
#include "gpio.h"
const uint8_t LED[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};const uint8_t LED_BASE[16] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};const uint8_t DIP[16] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 17};const uint8_t DIP_BASE[16] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3};
/* base: 0-4 corresponding to gpio/port groups A-E */static GPIO_Type * gpio_base_ptrs[5] = GPIO_BASE_PTRS;static PORT_Type * port_base_ptrs[5] = PORT_BASE_PTRS;
/******************************************************************************* Function: initGPDI* Description: Initialize a general purpose input based on port base and pin******************************************************************************/void initGPDI(const uint8_t base, const uint8_t pin){/* Set the pin direction to input */
/* Set the pin configuration register *//* Pin Mux Alt1 for GPIO */
/* All other bitfields to 0 *//* Internal pulldown or input filter are optional */
}
Array of LED pins, D0—D15
You do this …
lab1.c28
#include "S32K144.h"#include "gpio.h"/************************************************************************ * Function: section2* Description: Use the provided S32K144.h header file************************************************************************/
void section2(){uint16_t sum, value1, value2;int index;
for(index = 0; index < 16; index++){initGPDI(DIP_BASE[index], DIP[index]);initGPDO(LED_BASE[index], LED[index]);
}
Your lab1.c file will contain code something like:
… read DIPs, add and write to LEDs ...
Call initialization functions with Port (A-D) and Pin (0-15)
gpio.c29
/******************************************************************************* Function: initGPDO* Description: Initialize a general purpose output based on port base and pin
******************************************************************************/void initGPDO(const uint8_t base, const uint8_t pin){/* Set the pin direction to output */gpio_base_ptrs[base]->PDDR |= 0b1 << pin;
/* Pin Mux Alt1 for GPIO */port_base_ptrs[base]->PCR[pin] = PORT_PCR_MUX(0b001); /* Pin Mux
Alt1 for GPIO *//* All other bitfields to 0 */
}
Your gpio.c file will contain code something like …
30
• Use keyboard input instead of DIP switches
• Input 2 digits (0-9), calculate sum and output binary result to LEDs
•LPUART.c, LPUART.h provided
• ASCII to binary conversion (American Standard Code for Information Interchange)
ASCII Binary Decimal
011 0001 0001 1
011 0010 0010 2
… … …
011 1001 1001 9
Binary = ASCII & 0xF
Lab #1 Part 3: Read Serial Port and Write GPIO
31
Lab 1 GPIO
• Read the lab 1 documentation• Organize your file structure as described in
the lab assignment• Pre-lab
– Read the manual and answer the questions• In-lab• Post-lab
– Summarize the concepts learned in lab 1