PDA

View Full Version : Pointing to an interrupt vector


les@windstream
04-15-02, 01:32 PM
Another newbie question: On the MMC2107 there are timers with interrupts. How does one get the processor to jump to a MaxForth interrupt routine? (When the count down timer expires, I want it to execute a Forth word.) The simple mental model that I have for interrupt handling doesn't seem to match the hardware description in the MMC2107 manual. I assume I have to tell it the memory address of the word's CFA. But, I don't see an obvious register in which to put that address, or addresses for other interrupts. Thanks in advance for any suggestions.

rob
04-18-02, 05:10 AM
When programming with interrupts, there are a lot of pieces to get right (usually all of them) before you get it working. For the Mcore processor you will need to have the following two documents at your disposal (both available from Motorola in PDFs):

1. MMC2107 Technical Data Rev 2.0
This document discribes the peripherals, including the interrupt controller and the registers (memory-mapped, so accessable from Forth).

2. MCORE Reference Manual
This document discusses the core CPU, instructions and internal registers (not memory mapped, so accessable only from assembler).

To get interrupts going, you will need to set up the processor, the interrupt controller and the peripheral you wish to use. For debugging, you can just fake interrupts using the interrupt controller force interrupt registers.

Setting up the interrupt controller and peripheral is a matter of translating documentation into which register bits to twiddle and since these are all memory mapped, you can access them from Forth.

Setting up the processor is a little harder because you need to access its internal registers (PSR and VBR) which can only be done in assembler. I've put together the necessary Forth interface to access the control registers so it will make setting up interrupts a little easier:

( MCore interface to internal registers Rob Chapman April 18, 2002 )
HEX
( Assembly language interface to control registers )
CODE MFCR ( read control register into parameter field )
( lrw r4,ptr mfcr r3,crn stl r3,(r4,0} jmp r15 ptr: .+4, 0, )
74021003 , 930400CF , HERE 4 + , 0 , END-CODE
CODE MTCR ( write control register from parameter field )
( lrw r3,value mtcr r3,crn jmp r15 value: 0, )
73021803 , 00CF0000 , 0 , END-CODE

( Forth interface: Create an opcode with the given control register )
( and then store it in the code word before running it. )
: CRN@ ( control register -- contents ) ( return contents of control reg# )
10 * 74021003 OR ['] MFCR @ >R R@ ! MFCR R> C + @ ;

: CRN! ( value \ control register -- ) ( store value into control register )
10 * 73021803 OR ['] MTCR @ >R R@ ! R> 8 + ! MTCR ;

( Dump all the control registers )
: .CREGS ( -- ) CR D 0 DO I CRN@ 8 U.R CR LOOP ;

To set up an interrupt you'd follow these steps:
1. setup vector for interrupt routine
2. setup VBR and PSR (EE, IE)
3. setup interrupt controller (NIER)
4. setup peripheral

As for calling a Forth word from an interrupt, this is doomed to fail at some point since not all Forth words are interruptable. If you keep your interrupt simple and in assembler, then it has a greater chance of working.

I'll see if I can get an interrupt posted later as an example.

Rob

rob
04-19-02, 05:13 AM
Here's an interrupt routine which uses PIT1 to increment a counter:

HEX

( Assembly interface: use mtcr and mfcr to transfer contents of control )
( registers to and from memory )
CODE MFCR ( read control register into parameter field )
( lrw r4,ptr mfcr r3,crn stl r3,(r4,0} jmp r15 ptr: .+4, 0, )
74021003 , 930400CF , HERE 4 + , 0 , END-CODE

CODE MTCR ( write control register from parameter field )
( lrw r3,value mtcr r3,crn jmp r15 value: 0, )
73021803 , 00CF0000 , 0 , END-CODE

( Forth interface: Create an opcode with the given control register )
( and then store it in the code word before running it. )
: CRN@ ( control register -- contents ) ( return contents of control reg# )
10 * 74021003 OR ['] MFCR @ >R R@ ! MFCR R> C + @ ;

: CRN! ( value \ control register -- ) ( store value into control reg# )
10 * 73021803 OR ['] MTCR @ >R R@ ! R> 8 + ! MTCR ;

C50010 CONSTANT NIER ( normal interrupt enable register

CODE SIR-PIT
( mvi r4,13 lrw r3,pPCSR stb r4,(r3,0} lrw r4,ctr )
60D47303 , B4037404 ,
( addi r4,0 lrw r3,pctr stl r4,(r3,0} rte )
20047302 , 94030002 ,
C80001 , HERE 4 + , 0 , END-CODE

: .TICK ['] SIR-PIT @ 18 + @ . ;

' SIR-PIT @ 1 OR 801C28 !
1 NIER !
801C00 1 CRN!
80000140 0 CRN!
9FFFF C80000 !
.TICK .TICK .TICK

More details are in V.3 of the manual.

Rob