Jag försöker koppla en PS2 controller till min amiga CD32 men har stött på ett litet problem.
Select linan från amigan verkar inte orsaka någon extern interrupt i min PIC, jag har mätt pinnen med min logikanalysator och ser att jag får en high->low puls var ~39e ms som vara ~0.15ms men när jag kopplar den till PICen får jag ingen interrupt.
nedan följer koden som jag kör på min PIC men jag tror inte det är där problemet ligger eftersom jag kan få interrupts genom att manuellt driva den låg.
Kod: Markera allt
LIST P=18F4550 ; directive to define processor
#include <P18F4550.INC> ; processor specific variable definitions
CONFIG PLLDIV = 1 ; PLL prescaler 4/1=4 MHz (96MHz PLL needs 4 MHz from prescaler)
CONFIG CPUDIV = OSC4_PLL6 ; [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
CONFIG USBDIV = 2 ; if full speed (FSEN=1) USB is fed by PLL divided by 2 (96/2=48MHz)
CONFIG FOSC = HSPLL_HS
CONFIG BOR = OFF ; Disable Brown-out reset
CONFIG WDT = OFF ; Disable Watchdog timer
CONFIG FCMEN = OFF ; Disable Fail-Safe Clock Monitor
CONFIG LVP = OFF ; Disable low voltage ICSP
CONFIG DEBUG = OFF
;CBLOCK 0x0220 ; Declare variable addresses starting at 0x20
UDATA
RXDATA res 1
TXDATA res 1
JOYDIR res 1
JOYBUT res 1
JOYTYPE res 1
CONT1 res 1
CONT2 res 1
SERCNTR res 1
pack1 res 1 ; 1st byte of mouse data packet
pack2 res 1 ; 2nd byte of mouse data packet
pack3 res 1 ; 3rd byte of mouse data packet
xrot res 1 ; rotation byte for H and HQ
yrot res 1 ; rotation byte for V and VQ
delcnt res 1 ; delay counter
int_status res 1
int_w res 1
shiftreg res 1
shiftcounter res 1
;ENDC
CD32_SEL equ 2 ; In port B, to make use of edge-sensing interrupt. USING INT2
CD32_CLK equ 4 ; The rest of the CD32 lines occupy port A
CD32_DATA equ 5
CD32_UP equ 3
CD32_DOWN equ 1
CD32_LEFT equ 0
CD32_RIGHT equ 2
CODE 0x00
GOTO MAIN ;go to start of main code
ORG 0x08
; Interrupt routine - very time critical since we're
; simulating a serial shift register.
bsf TRISA,CD32_CLK
; The first bit should already be present since the
; first bit represents the Blue button, which is the
; data line's normal function. FIXME - can we improve compatibility by not putting
; the Blue button on the line until this point, or would it be too slow?
; We don't bother to watch the Select line, instead we
; let the watchdog timer rescue us if the comms break down.
waitclkhigh
btfss PORTA,CD32_CLK
goto waitclkhigh
; Put next bit on the data line
btfsc JOYBUT,6
bsf PORTA,CD32_DATA
btfss JOYBUT,6
bcf PORTA,CD32_DATA
waitclklow
btfsc PORTA,CD32_CLK
goto waitclklow
; Shift 1 bit left
RLNCF JOYBUT,1
clrwdt
decfsz shiftcounter,f
goto waitclkhigh
waitselhigh
btfss PORTB,CD32_SEL
goto waitselhigh
bcf INTCON3,INT2IF ; restore timer2 interrupt
; Restore port A
;BANK1
bcf TRISA,CD32_CLK
;BANK0
;movf portalatch,w
;movwf PORTA
; Reset shift counter for next time
movlw 0x07
movwf shiftcounter
; Restore regs
;swapf int_w,f
;swapf int_w,w
retfie 1
TransmitSPI:
BCF PIR1, SSPIF ;Make sure interrupt flag is clear (may have been set from previous transmission)
MOVF SSPBUF, W ;Perform read, even if the data in SSPBUF is not important
MOVWF RXDATA ;Save previously received byte in user RAM, if the data is meaningful
BCF T2CON, TMR2ON ;Turn off timer when loading SSPBUF
CLRF TMR2 ;Set timer to a known state
MOVF TXDATA, W ;WREG = Contents of TXDATA (user data to send)
MOVWF SSPBUF ;Load data to send into transmit buffer
BSF T2CON, TMR2ON ;Start timer to begin transmission
WaitComplete: ;Loop until data has finished transmitting
BTFSS PIR1, SSPIF ;Interrupt flag set when transmit is complete
BRA WaitComplete
MOVLW 0x30 ;Fix for SPI errata
CALL DELAY
MOVF SSPBUF, W ;Perform read, even if the data in SSPBUF is not important
MOVWF RXDATA ;Save previously received byte in user RAM, if the data is meaningful
RETURN
; ------------------------ delays -------------------------
DELAY:
MOVWF CONT1
LOOP1:
DECFSZ CONT1,F
GOTO LOOP1
RETURN
BIGDELAY:
MOVLW 0xFF
MOVWF CONT2
MOVLW 0x64
LOOP2:
CALL DELAY
DECFSZ CONT2,F
GOTO LOOP2
RETURN
DEL10: nop ; delay 10us
nop
nop
nop
nop
nop
RETURN
DEL200: movlw 0x42 ; delay 200us
movwf delcnt
DEL2: decfsz delcnt
goto DEL2
RETURN
MAIN:
;-------------------------------
; ENABLE SPI
;-------------------------------
MOVLW 0x30
MOVWF ADCON0
MOVLW 0x0F
MOVWF ADCON1
MOVLW 0x07 ; Configure comparators
MOVWF CMCON ; for digital output
CLRF PORTA
MOVLW 0xC0
MOVWF TRISA
CLRF PORTB
MOVLW 0xF9
MOVWF TRISB
MOVLW 0x07
MOVWF TRISC
CLRF CCP2CON
MOVLW 0x30
MOVWF CCP1CON
CLRF LATD
MOVLW 0xFF
MOVWF TRISD
; MOVLW 0x00
; MOVWF RCON
BSF LATB, 2
MOVLW 0x00
MOVWF INTCON2
MOVLW 0x90
MOVWF INTCON3
MOVLW 0xC6
MOVWF INTCON
MOVLW 0x00
MOVWF SSPSTAT
MOVLW 0x33
MOVWF SSPCON1
MOVLW 0x00
MOVWF SPPCON
;BANK1 ; Go to BANK 1
MOVLW 0x03 ;
MOVWF PR2 ; Set PR2 register to 0xFF
;BANK0 ; Go to BANK 0
MOVLW 0x06 ;Enable TMR2 set prescaler to 1/16
MOVWF T2CON
; MOVLW 0x00
; MOVWF SSPCON1 ; 0010 = SPI Master mode, clock = FOSC/64
;
; MOVLW 0x02
; MOVWF SSPCON1 ; 0010 = SPI Master mode, clock = FOSC/64
;
; MOVLW 0x0F
; MOVWF ADCON1 ; All analouge pins configured as digital pins.
;
; BSF TRISB,TRISB0 ; SDI must have TRISB<0> bit set (configure as digital in ADCON1)
; BCF TRISB,TRISB1 ; SCK (Master mode) must have TRISB<1> bit cleared
; BSF TRISC,TRISC7 ; SDO must have TRISC<7> bit cleared
; BCF TRISA,TRISA5 ; SS must have TRISA<5> bit set (configure as digital in ADCON1) for slave?
;
; BCF SSPSTAT,SMP ; Input data sampled at end of data output time
; BCF SSPSTAT,CKE ; Transmit occurs on transition from Idle to active clock state
;
; BSF SSPCON1,CKP ; Idle state for clock is a high level
; BSF SSPCON1,SSPEN ; Enables serial port and configures SCK, SDO, SDI and /SS as serial port pins
;BCF INTCON, GIE
BSF LATC,LATC6 ; Chip select Active Low
MOVLW 0xFF
MOVWF LATA
;-------------------------------
; SEND DATA
;-------------------------------
MAIN_LOOP:
;-------------------------------
; DISABLE INTERRUPTS
;-------------------------------
; MOVLW 0x00
; MOVWF INTCON
BCF LATC,LATC6
;-------------------------------
; SEND START COMMAND
;-------------------------------
; BYTE CMND DATA
MOVLW 0x80 ; 01 0x01 idle
MOVWF TXDATA
CALL TransmitSPI
;-------------------------------------------
; SEND DATA REQUEST, RECIEVE CONTROLER TYPE
;-------------------------------------------
MOVLW 0x42 ; 02 0x42 type
MOVWF TXDATA
CALL TransmitSPI
MOVF RXDATA, 0
MOVWF JOYTYPE
MOVLW 0xCE ; Check if the controller
SUBWF JOYTYPE,0 ; returns analogue type identifier
BTFSC STATUS,Z ; If analog identifier was returned
GOTO ANALOGUE ; call analogue control section
; else continue with digital control
MOVLW 0x00 ; 03 idle 0x5A Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TODO remove unnessecary W assignment
MOVWF TXDATA
CALL TransmitSPI
MOVLW 0x00 ; 04 idle data SLCT STRT UP RGHT DOWN LEFT
MOVWF TXDATA
CALL TransmitSPI
MOVF RXDATA, 0
MOVWF JOYDIR
MOVLW 0x00 ; 05 idle data L2 R2 L1 R1 /\ O X |_|
MOVWF TXDATA
CALL TransmitSPI
MOVF RXDATA, 0
MOVWF JOYBUT
BSF LATC,LATC6
; MOVLW 0xC6
; MOVWF INTCON
MOVF JOYDIR, W
MOVWF LATA
BTFSS JOYBUT, 0
BCF LATA,4
BTFSC JOYBUT, 0
BSF LATA,4
BTFSS JOYBUT, 1
BCF LATA,5
BTFSC JOYBUT, 1
BSF LATA,5
CALL BIGDELAY
GOTO MAIN_LOOP
ANALOGUE: ; Analogue Controller in Red Mode
MOVLW 0x00 ; 03 idle 0x5A Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 TODO remove unnessecary W assignment
MOVWF TXDATA
CALL TransmitSPI
MOVLW 0x00 ; 04 idle data SLCT JOYR JOYL STRT UP RGHT DOWN LEFT
MOVWF TXDATA
CALL TransmitSPI
MOVF RXDATA, 0
MOVWF JOYDIR
MOVLW 0x00 ; 05 idle data L2 R2 L1 R1 /\ O X |_|
MOVWF TXDATA
CALL TransmitSPI
MOVF RXDATA, 0
MOVWF JOYBUT
MOVLW 0x00 ; 06 idle data Right Joy 0x00 = Left 0xFF = Right
MOVWF TXDATA
CALL TransmitSPI
MOVLW 0x00 ; 07 idle data Right Joy 0x00 = Up 0xFF = Down
MOVWF TXDATA
CALL TransmitSPI
MOVLW 0x00 ; 08 idle data Left Joy 0x00 = Left 0xFF = Right
MOVWF TXDATA
CALL TransmitSPI
MOVLW 0x00 ; 09 idle data Left Joy 0x00 = Up 0xFF = Down
MOVWF TXDATA
CALL TransmitSPI
BSF LATC,LATC6
MOVLW 0xB4 ; put b'00101101' to xrot and yrot 2D
MOVWF xrot
MOVWF yrot
COMF JOYDIR, 0
BTFSS STATUS,Z
CALL MYMOVE
BTFSS JOYBUT, 0
BCF LATA,4
BTFSC JOYBUT, 0
BSF LATA,4
BTFSS JOYBUT, 1
BCF LATA,5
BTFSC JOYBUT, 1
BSF LATA,5
;movlw 0x0F
;ANDWF JOYDIR,0
;BTFSS STATUS,Z
;CALL MYMOVE
CALL BIGDELAY
goto MAIN_LOOP
MYMOVE
movlw 0x8
movwf pack3
BTFSS JOYDIR,0
CALL LEFT
movlw 0x8
movwf pack3
BTFSS JOYDIR,1
CALL DOWN
movlw 0x8
movwf pack3
BTFSS JOYDIR,2
CALL RIGHT
movlw 0x8
movwf pack3
BTFSS JOYDIR,3
CALL UP
;call MOVEY
RETURN
; --------------- conversion to Amiga format --------------
LEFT: call DEL200 ; send H and HQ for left movement
rlcf xrot
btfss STATUS,C
goto LH0
goto LH1
LH0: bcf xrot,0
bcf LATA,1
goto LHQ
LH1: bsf xrot,0
bsf LATA,1
LHQ: rlcf xrot
btfss STATUS,C
goto LHQ0
goto LHQ1
LHQ0: bcf xrot,0
bcf LATA,2
goto LONE
LHQ1: bsf xrot,0
bsf LATA,2
LONE: decfsz pack3
goto LEFT
return
RIGHT: call DEL200 ; send H and HQ for right movement
rrcf xrot
btfss STATUS,C
goto RHQ0
goto RHQ1
RHQ0: bcf xrot,7
bcf LATA,2
goto RH
RHQ1: bsf xrot,7
bsf LATA,2
RH: rrcf xrot
btfss STATUS,C
goto RH0
goto RH1
RH0: bcf xrot,7
bcf LATA,1
goto RONE
RH1: bsf xrot,7
bsf LATA,1
RONE: decfsz pack3
goto RIGHT
return
UP: call DEL200 ; send V and VQ for up movement
rlcf yrot
btfss STATUS,C
goto UV0
goto UV1
UV0: bcf yrot,0
bcf PORTA,3
goto UVQ
UV1: bsf yrot,0
bsf PORTA,3
UVQ: rlcf yrot
btfss STATUS,C
goto UVQ0
goto UVQ1
UVQ0: bcf yrot,0
bcf PORTA,0
goto UONE
UVQ1: bsf yrot,0
bsf PORTA,0
UONE: decfsz pack3
goto UP
return
DOWN: call DEL200 ; send V and VQ for down movement
rrcf yrot
btfss STATUS,C
goto DVQ0
goto DVQ1
DVQ0: bcf yrot,7
bcf LATA,0
goto DV
DVQ1: bsf yrot,7
bsf LATA,0
DV: rrcf yrot
btfss STATUS,C
goto DV0
goto DV1
DV0: bcf yrot,7
bcf LATA,3
goto KLAR
DV1: bsf yrot,7
bsf LATA,3
KLAR: decfsz pack3
goto DOWN
return
END
EDIT: Tog bort en vilseledande kommentar och la till lite mer information.