200 likes | 397 Views
UQC113S2. Interrupt Programming on 68307. 68307 Interrupt Handling. The 68307 has 2 distinct parts to the structure of its interrupt handling The standard 68000 core, called the EC000 core processor The 68307 Interrupt controller. Interrupt Handling. Order of Events.
E N D
UQC113S2 Interrupt Programming on 68307
68307 Interrupt Handling • The 68307 has 2 distinct parts to the structure of its interrupt handling • The standard 68000 core, called the EC000 core processor • The 68307 Interrupt controller
Order of Events • The Interrupt Controller collects events from on and off chip peripherals, orders them and send the highest priority to the EC000 core. • The EC000 core responds with and Interrupt Acknowledge (IACK) after completing the current instruction
Order of Events • The Interrupt Controller recognises the IACK and sends the interrupt vetor number of the highest priority interrupt • The EC000 core gets the vector, and reads the address of the ISR in the vector table and executes that routine
Generating Interrupts • Firstly the peripheral must be set up to generate interrupts • The Peripheral Interrupt Control Register (PICR) must also be initialised for that particular peripheral • The PICR will have the Interrupt Priority Level (IPL) for each interrupting peripheral
Peripheral Interrupt Control Register • T1 = Timer 1, T2 = Timer 2, UA =UART, MB = MBUS • IPL of 000 means no interrupts, 001-111 is the IPL for the interrupting peripheral
Minos Interrupt Handling irqhandler oldTvec; // set as interrupting on reaching reference value (0xffff) // installs isr using minos call // sets up interrupts on Peripheral interrrupt control to IPL 3 void timer(void) { unsigned short * Trr2; unsigned short * Tcn2; unsigned short * Tmr2; unsigned short * Picr; Tmr2 = (unsigned short *) 0x100130; Trr2 = (unsigned short *) 0x100132; Tcn2 = (unsigned short *) 0x100136; Picr = (unsigned short *) 0x100024; oldTvec = _getvect(0x4b); /* Save current handler address */ _setvect(0x4b,timeout); *Trr2 = (unsigned short) 0xffff; *Tcn2 = (unsigned short) 0x0000; *Tmr2 = (unsigned short) 0x801b;// 1000000000011011 reset, ints, restart master clock *Picr = *Picr | (unsigned short) 0x0300;// set the ints for timer 2 }
Minos Interrupt Handling int TFLAG = OFF; // isr for timer // clear timer event reg // wiggle led // set global time flag to 1 void _interrupt timeout(void) { unsigned char * Ter2; // clear the timer event reg bit for ref value Ter2 = (unsigned char *) 0x100139; *Ter2 = (unsigned char) 0x02; // wiggle led to let us know what is going on! #asm move.w $100018,D1 bchg #8,D1 move.w D1,$100018 #endasm // set global time flag to 1 = tick happened TFLAG=1; }
Minos Interrupt Handling void IRQstop( void ) { unsigned short * Tmr2; Tmr2 = (unsigned short *) 0x100130; *Tmr2 = (unsigned short) 0; _setvect(0x4b,oldTvec); }
Creating a Vector • Once a peripheral has interrupted a vector must be generated for it • This is done by the Programmable Interrupt Vector Register (PIVR) • The 8 bit vector is broken into 2 nibbles • A high nibble supplied by the system • A low nibble generated by the peripheral
Programmable Interrupt Vector Register • IV7-IV4 are set by the system, 0x40 on the CMS boards • Bits 3-0 are supplied, from a table, for each peripheral
Assembler ISR #include <stdio.h> #include <minos.h> #define MBASE 0x100000 #define PICR (MBASE + 0x24) //peripheral interrupt control register #define PIVR (MBASE + 0x27) #define TMR2 (MBASE + 0x130) //timer 2 mode register #define TRR2 (MBASE + 0x132) //timer 2 reference register #define TCN2 (MBASE + 0x136) //timer 2 count register #define TER2 (MBASE + 0x139) //timer 2 event register #define RESET_INT 0x2 //reset timer interrupts bit #define RESET_T 0x0 //reset(stop) timer void IRQstop( void ); void isr(void); void oframe(void); void T2setup( void ); extern int FPOINT; unsigned int * oldvec;
Assembler ISR main() { unsigned int * vect_tab1, *vect_tab2, *vect_tab3; vect_tab1 = (unsigned int*)(0x4b *4); // 0x40 = PIVR value 0xb = timer2 vect_tab2 = (unsigned int*)*(vect_tab1); //get isr from vector table #1 vect_tab2 =(char *) vect_tab2 + 2; // get rid of the extraneous 2 bytes!! vect_tab3 = (unsigned int*)*(vect_tab2); // get real ram isr address oldvec = *vect_tab3; //Save current handler address *vect_tab3 = (unsigned int*)isr; // install new isr routine T2setup(); while(!ready(fileno(stdin))) /* Loop until key pressed */ ; T2stop(); *vect_tab3 =oldvec; //restore old hanlder printf("oldvector address %x = %x, %x = %x, %x \n",vect_tab1, *vect_tab1,vect_tab2, *vect_tab2, oldvec); }
Assembler ISR void T2setup( void ) { unsigned short * Trr2; unsigned short * Tcn2; unsigned short * Tmr2; unsigned short * Picr; Tmr2 = (unsigned short *) TMR2; Trr2 = (unsigned short *) TRR2; Tcn2 = (unsigned short *) TCN2; Picr = (unsigned short *) PICR; *Trr2 = (unsigned short) 0xffff; //big number to count from *Tcn2 = (unsigned short) 0x0000; // reset counter *Tmr2 = (unsigned short) 0x801b; // ints, div by 16, prescale 0x80, start *Picr = *Picr | (unsigned short) 0x0100; / /IPL level 1 }
Assembler ISR //rather pointless routine called from isr – prints out frame pointer value void oframe(void) { printf("Frame pointer = %x\n",FPOINT); fflush(stdout); } void T2stop( void ) { unsigned short * Tmr2; Tmr2 = (unsigned short *)TMR2; *Tmr2 = (unsigned short) RESET_T; }
Assembler ISR SECTION __UDATA,D XDEF _FPOINT _FPOINT ds.l 1 frame pointer SECTION __CODE,C XREF _oframe XDEF _isr _isr movem.l a0/d0,-(sp) save register a0 & d0 on the stack move.w $100018,D0 wiggle led - what else! bchg #8,D0 move.w D0,$100018 movea.l #$100139,a0 addr of timer event reg move.b #2,(a0) clear event move.l a6,_FPOINT save frame pointer value into global jsr _oframe go and do C routine movem.l (sp)+,a0/d0 restore the regs rte let’s get out of here!