450 likes | 610 Views
Programming I/O for Embedded System. Overview. Basis: A DE2 Computer Architecture Parallel I/O 7-Segment Display Basic Manipulating 7-Segment Display on DE2 Interrupt and Interruption handling DE2 Internal Timer Basic Manipulating Internal Timer. Basis: A DE2 Computer Architecture.
E N D
Overview • Basis: A DE2 Computer Architecture • Parallel I/O • 7-Segment Display Basic • Manipulating 7-Segment Display on DE2 • Interrupt and Interruption handling • DE2 Internal Timer Basic • Manipulating Internal Timer
Basis: A DE2 Computer Architecture • A SOPC system on DE2 Board • Created by Quartus II • With a full featured I/O and memory devices integrated
System components • NIOS II Processor with on-chip memory • SDRAM • Flash Memory • Internal Timer • Parallel output ports to 8 green leds and 16 red leds • Parallel output ports to 8 on-board 7-segment leds • On-board LCD output • Parallel input ports to 16 switches • Parallel input ports to 4 push-buttons • JTAG-UART connection to host machine
Basis: A DE2 Computer Architecture • CPU: 32 bits word width, 50 MHz • On-Chip SRAM: 32 bits, 4KB • On-board SDRAM: 16bits, 8MB • On-board Flash Memory: 16 bits, 4MB • Internal Timer: period: 1ms • 3 Parallel I/O ports to LEDs and Switches: 8 bits • 8 Parallel I/O ports to 7-segment LED: 8 bits • On-board LCD: Optrex 16207 • JTG UART Serial Communication: 64 bits FIFO buffer
Interrupt request (IRQ) • Input device generated interrupts: push buttons : IRQ 2 JTAG_UART : IRQ 0 Internal Timer : IRQ 1 Interrupts provide an asynchronous way for data transmission between I/O devices and CPU
Address Map • Check sopc configuration for detailed Address map
Using HAL for embedded software development • HAL: Hardware Abstraction Layer • A programming interface for embedded system development, provide user a hardware-irrevelant programming platform Parallel I/O Communication Device Driver Interrupt and DMA control Video/Audio signal processing Ethernet/Internet access
Using HAL • HAL require a bunch of header files be included in user C source file, different HAL module require different header files • “system.h” includes the basic configuration of SOPC, Processor parameters, address and data bus width, I/O Address Map, should be included if HAL is used.
Parallel I/O • Parallel I/O is directly connected to processor pins, NIOS parallel I/O is addressed in 8-bit, and made up by 5 basic port registers: • Data Register • Direction Register • Interruptmask Register • Edge Capture Register • Outset Register • Outclear Register
Access to Parallel I/O port in NIOS • HAL integrated a group of macros and functions for I/O port access • Header file requested: #include “system.h” #include "altera_avalon_pio_regs.h“
Access to Parallel I/O port in NIOS IORD_ALTERA_AVALON_PIO_DATA(base) IOWR_ALTERA_AVALON_PIO_DATA(base,data) // Read and write to I/O Port IORD_ALTERA_AVALON_PIO_DIRECTION(base) IOWR_ALTERA_AVALON_PIO_DIRECTION(base,data) // Set/Get port direction IORD_ALTERA_AVALON_PIO_IRQ_MASK(base) IOWR_ALTERA_AVALON_PIO_IRQ_MASK(base, data) // Set/Get interrupt mask
Difference between direct assignment and using HAL Macro • We have already seen such code before #define PIO_ADDR 0x00000010 …. *((char *)PIO_ADDR)=(char) 0xff; Equivalent code using HAL Macro will be #define PIO_ADDR 0x00000010 IOWR_ALTERA_AVALON_PIO_DATA(PIO_ADDR,0xff) Difference? HAL provides a safety way for data transmission, user doesn’t need to be involved into complicated type cast and data alignment.
Constants definition in system.h • The constants in SOPC system s.t. I/O port and register file address, are defined in system.h. • For example, user have a 8-bit PIO port named switch_0_7 build in SOPC • The corresponding definition will be added to system.h • #define SWITCH_0_7_BASE 0x1803020
7-segment Display • Can display hex numbers (0-9,A-F) • Widely used in digital clock, temperature controller,etc
How board segment display works • Segment display on DE2 board is implemented as common-cathode 0x01803080
Connecting segment display to processor • the 7 pins of segment display can be connected to parallel I/O port and use parallel I/O operation to control the display on LED.
C Code Example of Segment Display #include “system.h” #include "altera_avalon_pio_regs.h” // #define SEG_LED_0_ADDR 0x01803080 // Or use the definition in system.h, which is SEG_LED_0_BASE main() { IOWR_ALTERA_AVALON_PIO_DATA(SEG_LED_0_BASE,0x30); ; //turn segment e and f off }
Push button • Push button is similar to switch, the difference is it need to be hold pressed down to keep the value on the parallel I/O port. • The way to read push button input is the same to switch
Interrupt handling and using internal timer • Two way for processor to accept external input: • Waiting for input: Processor will be halting and listening to the input port until data is transmitted while(data is not updated){ read data from address of some I/O port }
Interrupt handling and using internal timer • Interrupt: Data arrival will start an interrupt request to processor, when a interrupt is generated, processor will stop it’s current work and turn to interrupt service function (data receive), and resume work after interrupt is handled. interrupt_func() { transmit data from I/O port to processor } Main() { setup interrupt handling function }
Interrupt Request • “interrupt request" (or IRQ) is used to refer to either the act of interrupting the bus lines used to signal an interrupt, or the interrupt input lines on a Programmable Interrupt Controller • Generated when an I/O event occurs, handled by interrupt controller • Interrupts from different sources are differentiated by IRQ line number
Interrupt handler function • NIOS Processer keeps a special address in memory ad the entry point for interrupt handler function • Exception Vector: stores the address of interrupt handler function, when an IRQ is received by processor, it will save the instruction context and jump to interrupt handler function.
How to use interrupt handler • Enable corresponding IRQ line to processor in SOPC builder • Set I/O devices to enable external interrupt generation Enable the interruptmask register of Parallel I/O The ITO bit in internal timer control register • Write interrupt handler function • Register interrupt handler function
Code sample for interrupt handler setup • Include files: #include "system.h" #include "alt_types.h" #include "sys/alt_irq.h" #include "sys/alt_sys_init.h"
Pseudo-Code sample for interrupt handler setup void interrupt_handler() { … } main() { enable system irq register handler of irqX as interrupt_handler }
Internal Timer • NIOS Internal Timer • Works as a stop watch, period register and control signals are set by user by programming, once started, counter will count down from the value in period register to 0 and generate an interrupt when time is over.
Timer configuration Configured in SOPC Builder
How to use internal timer in programming • Internal timer will loopingly count down from value in period register to 0, when counter reaches 0, an interrupt on IRQ 1 will generated, user need to write IRS function for IRQ 1 to capture timer events • In DE2 Computer, the period of timer is 1 ms, means the interrupt will occur 1000 per second
How to use internal timer in programming • #include "system.h" • #include "alt_types.h" • #include "altera_avalon_timer_regs.h" • #include "altera_avalon_timer.h" • #include "sys/alt_irq.h" • #include "sys/alt_sys_init.h"
Macros for timer register file access • IORD_ALTERA_AVALON_TIMER_STATUS(base) • IOWR_ALTERA_AVALON_TIMER_STATUS(base, data) // Read/write to 16 bits status register • IORD_ALTERA_AVALON_TIMER_CONTROL(base) • IOWR_ALTERA_AVALON_TIMER_CONTROL(base, data) // Read/write to 16 bits control register • IORD_ALTERA_AVALON_TIMER_PERIODL(base) • IOWR_ALTERA_AVALON_TIMER_PERIODL(base, data) // Read/write to lower 16 bits of period register • IORD_ALTERA_AVALON_TIMER_PERIODH(base) • IOWR_ALTERA_AVALON_TIMER_PERIODH(base, data) // Read/write to higher 16 bits of period register
How to use internal timer in programming • Write user IRS function static void Timer_Interrupts(void *context,alt_u32 id) { if(Timer_counter >= 1000) /* 1S */ { Timer_counter = 0; //global variable to store reached counter event <USER CODE HERE> } else { Timer_counter++; } IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0x00);//clear status register }
How to use internal timer in programming • Register IRS alt_irq_register(TIMER_IRQ,NULL,Timer_Interrupts); //Register IRS IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE, 0x07); //Start timer
How to capture Timer event in user program • Keep a global variable for storing information from timer events, in main function, check the global variable to update timer events static int timer_event; interrupt_handler() { …. //set timer_event } main() { register IRS function while(timer_event updated) { … user actions } }
Summary • DE2 Computer A basic hardware configuration in Quartus for embedded system software design • Parallel I/O Basic, register file structure and programming • 7-Segment LED Driven by parallel I/O, programming and display • Interrupt handling Basic concepts, and how to use in programming • Internal Timer Basic, register file structure and programming