ECE 362 Lab Verification / Evaluation Form Experiment 3 Evaluation: IMPORTANT! You must complete this experiment during your scheduled lab perior. All work for this experiment must be demonstrated and verified by your lab instructor before the end of your scheduled lab period. STEP DESCRIPTION MAX SCORE 4.0 Prelab Questions 10 6.1 Digital Outputs 5 6.2 Digital Inputs 5 6.3 A Simple Embedded System 5 TOTAL 25 Signature of Evaluator: Student Name: Class #: - Signature: Date: https://engineering.purdue.edu/ece362 Page 1 of 11
1.0 Introduction Experiment 3: Embedded Hardware Over the past few lab sessions, students have learned about the microcontroller assembly language of the STM32F0, reading and writing simple segments of assembly code for performing functions. But microcontrollers are more than glorified simulation devices, and the purview of embedded programming is more than simple logical abstractions! In this experiment, students will learn how to use microcontroller I/O, the inputs and outputs, to sense and actuate devices in the world outside the chip. 2.0 Objectives 1. Flash an LED using STM32F0 outputs 2. Investigate button presses using STM32F0 inputs 3. Create a simple GPIO-based LED flasher 3.0 Equipment and Software 1. Standard ECE362 Software Toolchain (Installation instructions available in Experiment 0: Getting Started) 2. STM32F0-DISCOVERY development board (For procurement instructions, see Experiment 0: Getting Started) 4.0 Prelab 4.1 Read section 5 of this document for background information 4.2 Which document contains detailed descriptions of the registers used to configure I/O for the course microcontroller? Which section? 4.3 Which document contains specific implementation details for the course microcontroller, including device pinouts and electrical characteristics? 4.4 For general purpose I/O, what are the voltage limits of a microcontroller pin? How much current is the microcontroller able to sink (or source) over a single I/O pin? What is the maximum current rating for the entire device? 4.5 Which document contains details about the development board used by the course, including electrical schematics? 4.6 Which microcontroller pins are connected to the user output LEDs (LD3 and LD4) on the course development board? Which pin is connected to the user pushbutton (B1)? 4.7 Describe, in pseudocode, the series of steps needed to configure the I/O on the course microcontroller to interface to the user pushbutton (B1) and the user output LEDS (LD3 and LD4). https://engineering.purdue.edu/ece362 Page 2 of 11
Be sure to include which registers need to be written, their addresses, and what values need to be written to these registers. 5.0 Background 5.1 Cores, Microcontrollers, Development Boards, and Beyond For some ECE students, ECE362 in general (and this lab in particular) provides a student with their first experience with programmable embedded hardware. Embedded systems can be modeled as hierarchical designs composed of multiple levels, or layers of abstraction. With this in mind, it is useful at this point to take a step back and look at the embedded systems used in this course from the viewpoint of some of its layers of abstraction. 5.1.1 The Processor Core At the lowest level of the hardware hierarchy lies the processor, or core of the microcontroller. The processor is a collection of hardware whose function is to execute instructions written for it in a programming language (at the processor level, instructions are in the form of machine code; various software tools are used to convert from the assembly, C, and other programming languages to machine code). The processor core is the focus of the previous experiments of this course. For ECE362, the course microcontroller uses an ARM Cortex-M0 as its processor core. 5.1.2 The Microcontroller An engine is a useful mechanical module, capable of generating output power and torque. On its own, an engine does not perform useful work; it is only by wrapping the engine in a frame, adding wheels and other components to create a car, a complete mechanical system capable of performing tasks. In a similar fashion, various hardware subsystems and modules (memory, debugging circuitry, peripherals, I/O) are wrapped around the processor core to create the basic computing system known as the microcontroller. At the time of this writing, ECE362 uses the STM32F051R8T6 microcontroller, made by STMicroelectronics. This experiment will require students to interface to hardware modules outside of the Cortex-M0 processor core. 5.1.3 The Circuit Board A microcontroller is a computing system, with all of the modules and systems capable of performing useful computational work. That said, microcontrollers are seldom used as standalone devices. They are usually interfaced with various other electronic devices, including sensors, input devices (buttons, switches, knobs, levers, etc.), output devices (LEDs, LCDs, speakers, etc.), and more. Connections to these devices are usually done on a copper clad substrate material, the circuit board. At the time of this writing, ECE362 experiments use the STM32F0DISCOVERY development board for experiments. Putting the whole picture together, the ECE362 hardware model looks something like that shown in the figure below: https://engineering.purdue.edu/ece362 Page 3 of 11
5.2 Reset and Clock Control (RCC) Fig. 1. Course Embedded Hardware Overview Power conservation is one of the major objectives of ARM Cortex-series chips, and the STM32F0 series devices are no exception. To this end, many of the microcontroller's onboard systems are disabled (i.e. not provided a clocking signal) until such time as the clock is enabled to a given system in software. For STM32F0 devices, all GPIO interfaces are unclocked until such time as a clock signal is enabled to them. This is handled through a microcontroller system known as Reset and Clock Control, or RCC. RCC is described in detail in section 7 of the STM32F0x1 Family Reference manual, provided on the course website. Clock enable signals for the STM32F0 GPIO peripherals are provided in the AHB peripheral clock enable register, RCC_AHBENR. Writing a 1 to the corresponding I/O port clock enable bit will enable the clocking signal for the port. This is a necessary step in GPIO port configuration and should be the first step in the GPIO configuration process for a given port. 5.3 Microcontroller Inputs and Outputs Every microcontroller features a number of pins. Some pins have specialized functions, including providing the internal microcontroller circuitry with power and ground (supply pins), programming the device or providing debugging features (programming pins), and providing the microcontroller with clocking signals from external sources (clocking pins). The remaining pins on a given microcontroller are capable of taking on a wide variety of functions. One of the most basic of these functions, is what is referred to as general purpose input/output (GPIO). The circuitry associated with providing GPIO to a given group, or bank, of pins is referred to as a GPIO port. https://engineering.purdue.edu/ece362 Page 4 of 11
A GPIO pin (hereafter simply referred to as GPIO), is a pin which provides a simple digital input or output. A functional diagram for an STM32F0 GPIO port is shown in figure 2, below: Fig. 2. GPIO Functional Diagram From figure 2, it can be seen that GPIO ports control a number of important functions. A more thorough explanation of the STM32F0 microcontroller being used in this course (and other microcontrollers within the same device family) is given in the GPIO section of the STM32F0x1 Family Reference datasheet, given on the course website. Major GPIO functionality and associated registers are described below: Direction: Direction involves specifying the flow of data through a given GPIO; each pin is able to be configured as either an input or output. Direction is controlled via the GPIOx_MODER register (x indicates which port is being chosen). Four choices are available: input, output, alternate function (AF), or analog. Drive Type: Drive type can be thought of as how strongly a pin is being driven. Drive type is controlled by the GPIOx_OTYPER register. Two options are available: open drain (a transistor is connected to the logic low voltage, useful for connecting to large numbers of logical gates together with a pull-up resistor) or push-pull (transistors are connected to the logic low and high voltages, useful for 'strongly' driving a given I/O pin). Speed: Depending on the application, a GPIO can be configured as a high-speed input or output. This is controlled by the GPIOx_SPEEDR register. Pull-up/Pull-down: Many GPIO connections will be used to interface to other logic. In these applications situations may arrive where no circuitry is driving a given line or bus; the line is said to be floating. Floating lines can behave unpredictably; one solution is to use pull-up https://engineering.purdue.edu/ece362 Page 5 of 11
or pull-down resistors. These are high-valued resistors which provide a very low current path to Vdd or Ground. When a line is left floating, the resistors pull the floating line to a supply rail (Vdd or Ground). Pull-up resistors are controlled via the GPIOx_PUPDR register. In addition to these GPIO configuration features and registers, there are 3 additional functions and registers for GPIO that are worthy of consideration: Input Data Register: If a given GPIO port pin has been configured as a digital input, there needs to be a place in software where the value on the digital input is stored and available for use by the processor. This place is the GPIOx_IDR register. The lower 16 bits of this register are readonly bits containing the input values of the GPIO pins for a given port. Output Data Register: Once a given GPIO port pin has been configured as a digital output, the output value of that pin can be controlled in software. This is done through the GPIOx_ODR register. The lower 16 bits of this register can be read or written to by software. Writing a 0 or 1 to one of the bits in the GPIOx_ODR register outputs a logic 0 or 1 on the corresponding GPIO port pin. Port Bit Set/Reset Register: Configuring GPIO port output values using the GPIOx_ODR register works out acceptably in many situations. At the assembly level, however, when an individual pin needs to be set or cleared (reset), the following sequence of operations must be followed: Read in value of GPIOx_ODR regster Perform a logical AND or OR of the register with a given bit mask Write the new value back to the GPIOx_ODR register This requires 3 assembly instructions to perform. In applications where high-speed toggling of GPIO pins is required, or in situations where frequent interrupts are a possibility, this 3-step read-modify-write process may not be acceptable. For these contingencies, STM provides the GPIO port bit set/reset (GPIOx_BSRR) registers, which allow for atomic bit set and reset. Atomic means that the whole process occurs in one indivisible step; once one of the reset (bits 31:16) or set (bits 15:0) of this register have been modified, the set or reset of the associated ODR bit occurs quickly and automatically, and cannot be interrupted by software. 5.4 Example: ARM Cortex M0 Registers Given all of the registers described in the previous sections, an important implementation detail arises: how are these registers accessed by software to manipulate GPIO and other peripherals? The answer to this question lies in two important pieces of documentation: the memory map and the peripheral register documentation. The memory map is a piece of documentation which details where in memory allocations are made for various microcontroller systems. The memory map for the STM32F0 microcontroller used in ECE362 is detailed in section 2.2 (Memory Organization) of the STM32F0x1 Family Reference manual. A portion of the memory map is shown below: https://engineering.purdue.edu/ece362 Page 6 of 11
Fig. 3. Partial STM32F0 Memory Map Address locations and sector sizes within memory for various microcontroller systems are described in the memory map. Suppose, for example, that we wish to configure the clocking interface for one of the GPIO ports (GPIOB). As detailed in section 5.2, that functionality falls under the domain of the RCC. From the memory map, we can see that 1kB of memory space, starting at address 0x40021000, is reserved for the RCC. Once the microcontroller system of interest is known, the documentation for that system is further described within its own section in the device Family Reference Manual. For the RCC, this is described in section 7 of the manual. Going to that section provides abundant notes and information about the system, its configuration and usage. Section 7.4 (RCC Registers) provides a complete listing of the various registers used in configuration and operation of the RCC. The documentation for the register of interest (RCC_AHBENR) is provided below: https://engineering.purdue.edu/ece362 Page 7 of 11
Fig. 4. Register Documentation Example This register entry is rife with useful content. Starting from the top, the register's address offset (0x14) within the RCC's memory space is provided. Next, the initial value of the register following system reset is detailed. If there are any special caveats to accessing the register, they are provided in the Access section. Special notes are given following that. The meat of the register documentation follows, with a full breakdown of all 32 bits of the register, along with names of the bits and whether they can be read, written, or both by software. Following the table are descriptions of every bit in the register and their functions. Putting all of this together, some pseudocode for configuring the clock to GPIOB is provided below: https://engineering.purdue.edu/ece362 Page 8 of 11
Constant: RCC, #0x40021000 Constant: AHBENR, #0x14 1. Load register A with RCC memory address 2. Load register B with AHBENR memory address offset //RCC peripheral starting memory address //AHBENR register address offset from starting address 3. Load register C with value of register RCC_AHBENR (located at address RCC + AHBENR) 4. Load register D with a bitmask containing the bits that need to be set (or cleared) in register C 5. Perform logical operation (logical OR for bit sets, logical AND for bit clears) between registers C and D, store result to register C 6. Store modified value of RCC_AHBENR (register C) to memory location of register RCC_AHBENR (located at address pointed to by register A + register B) 6.0 Experiment 6.1 Digital Outputs Based on the information contained in section 5 and the pseudocode written in the prelab exercises, create a code segment which performs the function described below. Demonstrate the completed code segment to your TA. Description: Write a piece of code which configures the microcontroller pin corresponding to LD4 (blue LED) on the STM32F0 discovery board as a standard digital output. Once configured, output a logic 1 on this pin, lighting up the blue LED. Useful Assembly Instructions and Directives: (See ARMv6-M Architecture Manual for details).equ (Used by GNU assembler to define constants) LDR (literal) LDR (register) ORR (register) STR (register) Other Hints: When debugging your code, in addition to knowing the values of the various processor registers, it will be helpful to be able to examine the values of the various peripheral registers utilized by the microcontroller. For this purpose, consult the I/O Registers tab in the Monitor window. This tab provides a hierarchical listing of all of the various peripherals utilized by the microcontroller and their sub-registers. By default their values are not shown; double clicking on a given entry will cause the debugger to track the values of that entry and its lower elements. Use this to confirm that the various registers you are writing to are taking on the values which you expect. An example of this is shown in figure 5, below: https://engineering.purdue.edu/ece362 Page 9 of 11
Fig. 5. I/O Registers View 6.2 Digital Inputs Based on the information contained in section 5 and the pseudocode written in the prelab exercises, create a code segment which performs the function described below. Demonstrate the completed code segment to your TA. Description: Write a piece of code which configures the microcontroller pin corresponding to B1 (the blue button) as a standard digital input. When running, the GPIOx_IDR bit corresponding to your button pin should change value when the button is pressed (see the I/O registers view). Useful Assembly Instructions and Directives: (See ARMv6-M Architecture Manual for details).equ (Used by GNU assembler to define constants) LDR (literal) LDR (register) ORR (register) STR (register) Other Hints: Consult the circuit diagram for the STM32F0 discovery board, noting the implementation https://engineering.purdue.edu/ece362 Page 10 of 11
of button B1. What value does PA0 expect when the button is not pressed? When the button is pressed? 6.3 A Simple Embedded System Combining the knowledge of lab sections 6.1 and 6.2, create a code segment which performs the function described below. Demonstrate the completed code segment to your TA. Description: Write a piece of code which configures the microcontroller pins for B1 (blue button) as a standard digital input, and LD3 and LD4 (the blue and green LEDs) as standard digital outputs. Once done, your code segment should activate the blue LED when button B1 is not pressed (green LED should not be lit). When button B1 is pressed, the blue LED should be turned off and the green LED should be turned on. Useful Assembly Instructions and Directives: (See ARMv6-M Architecture Manual for details) B Other Hints: This code segment requires conditional execution with the branch command to work properly. See section A6.3 (Conditional Execution) of the ARMv6-M Architecture Manual for additional information regarding conditional execution and how it is used. 7.0 Sources Cited [1] Understanding the STM32F0's GPIO part 1. [Online] Available: http://hertaville.com/stm32f0- gpio-tutorial-part-1.html https://engineering.purdue.edu/ece362 Page 11 of 11