rob
09-07-00, 11:34 AM
( Interrupt example for MaxForth V5.0L Rob Chapman Sep 7, 2000 )<br>( The actual interrupt vector is in protected flash but it basically<br>( jumps to the vector stored at 800 less its location. For instance<br>( the Real Time interrupt vector is FFF0 but the location you want<br>( to put the address of your interrupt routine is at FFF0 - 0800<br>( or F7F0. This can be done with FL!. <br>( In this example, the interrupt vector is pointed to EEPROM where<br>( a jump is done to the real interrupt routine in RAM.<p>COLD<br>HEX<br>( ==== Interrupt control ==== )<br>CODE-SUB +INT<br> 10EF , ( cli ; enable interrupts<br> 3D C, ( rts<br>END-CODE<p>CODE-SUB -INT<br> 1410 , ( sei ; disable interrupts<br> 3D C, ( rts<br>END-CODE<p>: COLD -INT COLD ;<p>( ==== Real time interrupt interface tools ==== )<br>( ==== Registers ==== )<br> 14 CONSTANT RTICTL ( real time interrupt control register<br> 15 CONSTANT RTIFLG ( real time interrupt flag register<br> 1E CONSTANT INTCR ( IRQ control register<p>( ==== Real time interrupt ==== )<br> VARIABLE ticks ( incremented by RTI interrupt )<p>CODE-SUB SIR-RTI ( real time interrupt: increment a ticker<br> 4D C, RTIFLG C, 7F C, ( BCLR RTIFLG,$7F ; clear RTIF<br> FE C, ticks , ( LDX ticks ; get timer contents<br> 08 C, ( INX ; increment it<br> 7E C, ticks , ( STX ticks ; store it back<br> 0B C, ( RTI ; return from interrupt<br>END-CODE<p>( The interrupt vector is stored in EEPROM so it can be compiled<br>( and changed many times. The location in Flash can only be changed<br>( by clearing all of the flash. So it is always the same.<br>FFD F7F0 FL! ( interrupt vector is in EEPROM<br>06 FFD EEC! ' SIR-RTI @ FFE EE! ( jmp to interrupt<p>DECIMAL<br>( ==== Time supplements ==== )<br> VARIABLE start-time<p>: MSEC ( n -- n' ) 4 + 1000 UM* 4096 UM/MOD SWAP DROP ;<br>: SEC ( n -- n' ) 1000 * MSEC ;<br>: TIME ( -- n ) ticks @ ;<br>: WAIT ( n -- ) TIME >R BEGIN DUP TIME R@ - U< ?TERMINAL OR UNTIL<br> R> 2DROP ;<br>: START ( -- ) TIME start-time ! ;<br>: FINIS ( -- ) TIME start-time @ - 0 1 SEC UM/MOD ?DUP<br> IF 0 U.R ." ." 4096 UM* 1000 UM/MOD<br> 4 - 0 MAX 0 <# # # # #> TYPE ." sec"<br> ELSE 4096 UM* 1000 UM/MOD 4 - U. ." msec" THEN DROP ;<p>( START and FINIS can be used to time things. Try: START 10 SEC WAIT FINIS )<p>HEX<br>( ==== initialization ==== )<br>: INIT-RTI ( -- ) -INT ( disable interrupts )<br> INTCR C@ BF AND INTCR C! ( disable IRQ interrupts )<br> 83 RTICTL C! ( enable real time interrupt at 4ms )<br> +INT ; ( enable interrupts )<p>( Test sequence:<br>INIT-RTI<br>DECIMAL CR .( NOW ) START 2 SEC WAIT FINIS .( LATER )<br>