Top Banner
NIOS Interrupts Last updated 10/24/19
24

NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

May 29, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

NIOS Interrupts

Last updated 10/24/19

Page 2: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

2 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• 2 Options for dealing with interrupts

• Internal Interrupt Controller – IIC

• External Interrupt Controller - EIC

• The IIC has two versions• Legacy API

• Enhanced API

Page 3: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

3 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• On an interrupt or exception the processor• Saves the current status

• Disables HW interrupts

• Saves the next execution address (Program Counter)

• Transfers control to the exception handler

• What about all the registers?• NIOS supports shadow registers

• Remove the need to save the registers to the stack

Page 4: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

4 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Support for 32 interrupt signals

• Interrupt # indicates inverse priority**

• We set these in QSYS

** Managed by the HAL SW

Page 5: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

5 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• The HAL Internal Interrupt framework uses a single exception controller

• We set the address for the “exception handler” when we instantiate the NIOS II processor

Page 6: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

6 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• The single Exception handler

• Handles exceptions and interrupts

• Exception handler keeps a table of ISR priorities

• To be included in the table – we must “register” the IRQ of each module

Page 7: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

7 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Legacy Exception Handler Functions• ALT_LEGACY_INTERRUPT_API_PRESENT in system.h

alt_irq_register() alt_irq_interruptible()

alt_irq_disable() alt_irq_non_interruptible()

alt_irq_enable() alt_ic_irq_enabled()

alt_irq_disable_all()

alt_irq_enable_all()

Page 8: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

8 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Enhanced Exception Handler Functions• ALT_ENHANCED_INTERRUPT_API_PRESENT in system.h

alt_ic_isr_register()

alt_ic_irq_disable()

alt_ic_irq_enable()

alt_irq_disable_all()

alt_irq_enable_all()

alt_ic_irq_enabled()

Page 9: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

9 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Register prototype

int alt_ic_isr_register(

alt_u32 ic_id, interrupt controller ID

alt_u32 irq, interrupt ID

alt_isr_func isr, isr name

void * isr_context, pointer to any passed context

void * flags reserved - 0

);

Page 10: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

10 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts• Register prototype

interrupt controller ID – not used with IIC - 0

interrupt ID – from system.h

isr name – your choice

pointer to any passed context – e.g PIO input value

#define SW_PIO_HAS_IN 1

#define SW_PIO_HAS_OUT 0

#define SW_PIO_HAS_TRI 0

#define SW_PIO_IRQ 10

#define SW_PIO_IRQ_INTERRUPT_CONTROLLER_ID 0

#define SW_PIO_IRQ_TYPE "EDGE"

#define SW_PIO_NAME "/dev/sw_pio"

#define SW_PIO_RESET_VALUE 0

#define SW_PIO_SPAN 16

#define SW_PIO_TYPE "altera_avalon_pio"

Page 11: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

11 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• ISR prototype

void isr(void * context)

void pointers do not have a typevoid pointers can point to any typevoid pointers cannot be dereferencedvoid pointers can be cast to any typepointer arithmetic is not allowed with void pointers

Page 12: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

12 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Example

• Modify our counter project to increment the count based on a switch rising edge – via interrupt

• Use the edge capture flag as the signal to increment the counter

Page 13: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

13 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts• Edit sw_pio

Page 14: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

14 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

Page 15: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

15 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

Page 16: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

16 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

#include "system.h"

#include "altera_avalon_pio_regs.h"

#include "sys/alt_irq.h"

#include "alt_types.h"

#include <stdio.h>

Page 17: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

17 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

Choose a name for ISR

Create a global variable

Create a void * pointer to the global variable

Register the ISR – passing the context in via the

void * pointer

Create an appropriate type

pointer

Cast the context void * pointer to the appropriate

type pointer

Modify the appropriate type pointer as usual

ISR

foo

foo_ptr

void *

my_ptr

int *

context

cast

(*my_ptr)++;

incrementfoo

int

Page 18: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

18 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

// ISR Prototypevoid io_switch_isr(void * context);

Page 19: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

19 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

// Global variable to hold the value of the// edge capturevolatile int edge_val;

Page 20: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

20 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

// Cast the global variable to the required ISR// type of pointer - void *void * edge_val_ptr = (void *) &edge_val;

Page 21: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

21 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

// Register the interruptalt_ic_isr_register(

SW_PIO_IRQ_INTERRUPT_CONTROLLER_ID,SW_PIO_IRQ,io_switch_isr,edge_val_ptr,0x00

);

int alt_ic_isr_register(alt_u32 ic_id, interrupt controller IDalt_u32 irq, interrupt IDalt_isr_func isr, isr namevoid * isr_context, pointer to any passed contextvoid * flags reserved – 0

);

system.h

sys/alt_irq.h

Page 22: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

22 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

void io_switch_isr(void * context){// expect the context passed to be a pointer// to the variable to hold the edge capture information

// create a pointer variable to hold the contextvolatile int * edge_ptr;edge_ptr = (volatile int *) context;

// Read the edge capture register and assign the// value to the ptr variable*edge_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE);

// Clear the edge capture registerIOWR_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE, 0);

} // end io_switch_isr

Page 23: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

23 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

int main(void){

printf("Entered main\n");

int count = 0;

// Configure the IO switches

io_switch_setup();

// Loop and wait for edges to update the count

while(1){

if(edge_val & 0x01){

count++;

edge_val = 0;

printf("incrementing count : %i\n", count);

} else if (edge_val & 0x02){

count--;

edge_val = 0;

printf("decrementing count : %i\n", count);

}

// Output the count to the LEDs

IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, count);

}

} // end main

/*

* nios_interrupts.c

*

* Created on: Sep 20, 2018

* Author: johnsontimoj

*/

#include "system.h"

#include "altera_avalon_pio_regs.h"

#include "sys/alt_irq.h"

#include "alt_types.h"

#include <stdio.h>

// ISR Prototype

void io_switch_isr(void * context);

// Switch setup prototype

void io_switch_setup();

// Global variable to hold the value of the

// edge capture

volatile int edge_val = 0;

Page 24: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

24 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

void io_switch_setup(void){

// Enable interrupts on 2 switches

IOWR_ALTERA_AVALON_PIO_IRQ_MASK(SW_PIO_BASE, 0x03);

// Clear any existing interrupts

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE, 0x00);

// Cast the global variable to the required ISR

// type of pointer - void *

void * edge_val_ptr;

edge_val_ptr = (void *) &edge_val;

// Register the interrupt

alt_ic_isr_register(SW_PIO_IRQ_INTERRUPT_CONTROLLER_ID,

SW_PIO_IRQ,

io_switch_isr,

edge_val_ptr,

0x00);

} // end io_sw_setup

void io_switch_isr(void * context){

// expect the context passed to be a pointer

// to the variable to hold the edge capture information

//

// create a pointer variable to hold the context

volatile int * edge_ptr;

edge_ptr = (volatile int *) context;

// Read the edge capture register and assign the

// value to the ptr variable

*edge_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE);

// Clear the edge capture register

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE, 0);

} // end io_switch_isr