Content-Type: TEXT/PLAIN; CHARSET=US-ASCII Content-ID: Hi fellows, I'm really atonished with a problem that's ocurring with my present project. I use TMR0 interrupt in 2 ways: (1) as a single pulse detector, attached to PA4 input, generating a physical interrupt, (2) as a timing counter of machine cycles. This is done to get some more speed in decoding a 38400 bps line, _at_the_same_time_ a PCAT standard keyboard is polled in the PB0/INT pin. For this last, the interrupt enable flag INTE is _disabled_, and the INTF flag is supposed (as stated in the data sheet) to be set when the chosen transition occurs at this pin, regardless the state of INTE. What seems to be wrong is that there _occurs_ interrupts, even if the keyboard isn't attached (yes, I've put some pull-ups in the inputs), and nothing more is using PORTB bits! I've not been able to isolate the problem, so I'm posting it here to see if some bright mind may help me. Sorry, because it's too extensive for this list, but I have no way to clean any more :( Please read carefully the attached source and try to find where I'm wrong (or perhaps, Microchip). regards, Rildo Pragana Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; NAME="kvmail.asm" Content-ID: Content-Description: the source with problems ;******************************************************************* ; LIST p=16C84 ;target processor INCLUDE p16c84.inc __CONFIG 019h ;CP off, PWRTE on, WDTE off, XT osc radix DEC ; w equ 0 f equ 1 dir_a equ 00010000b ;_lin as input dir_b equ 01000111b ;_kbd, _kbc as inputs (some not defined here) ; #define _c STATUS,C #define _z STATUS,Z #define _rp0 STATUS,RP0 #define _t0if INTCON,2 #define _gie INTCON,7 #define _inte INTCON,4 #define _rbie INTCON,3 #define _intf INTCON,1 #define _rbif INTCON,0 #define _t0ie INTCON,5 #define _t0cs OPTION_REG,5 #define _t0se OPTION_REG,4 #define _psa OPTION_REG,2 ;----------------------------------------------------------------- ; #define _lin PORTA,4 ;line input #define _enb PORTA,3 ;line transmitter enable #define _lou PORTA,0 ;line output ; #define _kbd PORTB,1 ;keyboard data #define _kbc PORTB,0 ;keyboard clock ; #define _kct TRISB,0 ;keyboard clock tri-state control ; #define _sbf flags,0 ;start bit found #define _pol flags,1 ; clockrate equ .6144000 ;crystal frequency baudrate equ .38400 ;line bit rate fclk equ clockrate/4 ;processor instruction rate ; kbcnt equ 10h kbdat equ 11h w_tmp equ 14h st_tmp equ 15h flags equ 16h ; 0=_sbf, 1=_pol (1=normal [idle=high]) bitcnt equ 1ah kbst equ 1bh lindat equ 1ch ; org 0 goto start org 4 goto intr ; #define MAXKBST 5 ;maximum kbd machine state (read finished) ; kbsw movf kbst,w ;1 entry point for keyboard state machine addwf PCL,f ;2 goto kst0 ;2+2 total=7 state 0 goto kst1 ;state 1 goto kst2 goto kst1 goto kst3 goto kst4 ;state 5 ;---------------------------------------------------------------------- intr swapf w_tmp,f ;1 save w and status swapf STATUS,w ;1 movwf st_tmp ;1 bsf _rp0 ;1 bcf _t0cs ;1 switch to internal clock in TMR0 bcf _rp0 ;1 bcf _t0ie ;1 no more interrupts, please bcf _t0if ;1 bsf _sbf ;1 movlw -.26 ;1 mark time for end of 1 1/2 bit movwf TMR0 ;1 ; iend swapf st_tmp,w ;1 recover w and status movwf STATUS ;1 swapf w_tmp,w ;1 retfie ;2+2 ;------------------------------------------------------------------- kst0 bsf _rp0 ;1 set _kbc for input (keyboard clock) bsf _kct ;1 bcf _rp0 ;1 movlw .8 ;1 restart counter movwf kbcnt ;1 movf PORTB,w ;1 read to set input latches incf kbst,f ;1 goto next state bcf _intf ;1 clear PB0/INT flag goto dly4 ;4 total = 7+12 = 19 cycles kst1 btfss _intf ;2/1 aguarda start bit (ou parity,stop bit) goto dly11 ;;11 incf kbst,f ;1 bcf _intf ;1 goto dly8 ;8 total = 19 cycles kst2 btfss _intf ;2/1 check if INT ocurred goto dly11 ;;11 rrf kbdat,f ;1 rotate data byte right bcf kbdat,7 ;1 clear bit before testing btfsc _kbd ;2 test if bit must be set bsf kbdat,7 ; set it (mirror pin) bcf _intf ;1 ready to next INT decfsz kbcnt,f ;2/1 count down goto dly4 ;;4 incf kbst,f ;1 next state return ;2 total=12+7=19 cycles kst3 btfss _intf ;2/1 check for INT goto dly11 ;;11 not yet, complete timing bcf _kbc ;1 clear, preparing for output bsf _rp0 ;1 bcf _kct ;1 enable output (keyboard clock) for ACK bcf _rp0 ;1 incf kbst,f ;1 next state bcf _intf ;1 clear INT flag goto dly4 ;4 total=19 cycles kst4 goto dly12 ;12+7 wait till someone take it off here ; dly13 nop ;some delay routines dly12 nop dly11 nop dly10 nop dly9 nop dly8 nop dly7 nop dly6 nop dly5 nop dly4 return ;------------------------------------------------------------------- prstrt bcf _t0ie ;momentaneous disable bsf _rp0 bsf _t0cs ;select RA4/T0CKI as TMR0 source bcf _t0se ;select polarity of transition btfsc _pol ;...according _pol (flag) bsf _t0se bcf _rp0 bcf _t0if ;clear TMR interrupt flag movlw 0ffh ;set TMR0 register just before overflow movwf TMR0 bsf _t0ie ;enable TMR interrupt return ;------------------------------------------------------------------- rdlin call kbsw ;keep keyboard reading on movlw .8 ;init line bit counter movwf bitcnt call prstrt ;prepare to interrupt on start bit rdlinm call kbsw ;keep kbd reading... btfss _sbf goto rdlinm bcf _sbf rdl1 btfss _t0if ;wait for end of timing (1 1/2 bit) goto rdl1 rdl2 rrf lindat,f ;1 bcf lindat,7 ;1 btfsc _lin ;2 bsf lindat,7 decfsz bitcnt,f ;2/1 goto rdl3 ;;2 subtotal=7 movlw 0ffh ;if necessary, negate data btfss _pol xorwf lindat,f return rdl3 call kbsw ;19 call dly12 ;12 goto rdl2 ;2 total=40 ;------------------------------------------------------------------- wrlin movwf lindat call kbsw movlw 0ffh btfss _pol xorwf lindat,f ;change if _pol movlw .8 movwf bitcnt bcf _lou ;start bit btfss _pol bsf _lou ;according _pol bsf _enb ;enable transmitter (time critical) call dly8 ;start bit may last for 2 more cycles wrli1 call kbsw ;19 call dly13 ;13 btfsc lindat,0 ;2 bit to send bsf _lou btfss lindat,0 ;2 bcf _lou rrf lindat,f ;1 decfsz bitcnt,f ;2/1 goto wrli1 ;;2 call kbsw ;delay for the last bit call dly13 bcf _enb ;disable transmission goto kbsw ;19 ;------------------------------------------------------------------- start bsf _rp0 movlw dir_b movwf TRISB movlw dir_a movwf TRISA bcf _rp0 clrf PORTA clrf PORTB bsf _rp0 movlw 00101000b ;w/pull-ups, falling edge rb0/int (intedg) ;t0cs = ra4 pin, t0se = falling edge ;psa=no prescaler, ps2,1,0=1:1 movwf OPTION_REG bcf _rp0 clrf INTCON bsf _gie ; bcf _kbc ;1 bsf _rp0 ;1 bcf _kct ;1 clock (low), blocking bcf _rp0 ;1 clrf kbst bcf _intf ; ; --- determine line polarity --- pl1 movlw .12 ;must stay idle 12 bit time movwf bitcnt bcf _sbf ;clear "start bit found" flag bcf _pol ;_pol ;---- look for current line state and choose loop accordingly ---- btfsc _lin goto pl2aa ; pl2b btfsc _lin ;2 goto pl1 ;restart if line changed goto $+1 ;2 decfsz bitcnt,f ;2/1 goto pl3b ;;2 subtotal=7 goto pl4 pl3b call kbsw ;19 call dly12 ;12 goto pl2b ;2 total=40 ; pl2aa bsf _pol ;line already high pl2a btfss _lin goto pl1 ;restart if changed goto $+1 decfsz bitcnt,f ;2/1 goto pl3a ;;2 goto pl4 pl3a call kbsw ;19 call dly12 ;12 goto pl2a ;2 total=40 pl4 ;------------------------------------------------------------------ loop1 call delay ;fill time (delay) reading keys loop call rdlin ;read char from line ; call delay ; movf lindat,w ; call wrlin ;write it back (echo) movlw MAXKBST xorwf kbst,w ;check if local key available btfss _z goto loop1 ;no, keep looking call delay movf kbdat,w call wrlin ;send key read to host clrf kbst ;restart kbd machine clrf kbdat goto loop1 ; delay call kbsw call kbsw goto kbsw ; END ;