; RFID PIC Module ; This module: ; (1) Receives RFID bytes from RDM630 RFID card reader over UART ; (2) Sends the exact message over to the Security PIC over SPI ; ; PORT DIAGRAM AND PINOUT FOR RFID PIC ;************************************************* ; 1 +5V VDD VSS GND 20 ; 2 OSC1 PORT A5 PORT A0 RFID_READY 19 ; 3 OSC2 PORT A4 PORT A1 18 ; 4 PORT A3 PORT A2 17 ; 5 PORT C5 PORT C0 16 ; 6 PORT C4 PORT C1 15 ; 7 PORT C3 PORT C2 14 ; 8 SPI-SS PORT C6 PORT B4 SPI-SDI 13 ; 9 SPI-SDO PORT C7 PORT B5 RX 12 ; 10 PORT B7 PORT B6 SPI-SCK 11 ;************************************************* list P=PIC16F690 #include "p16F690.inc" __config (_MCLRE_OFF & _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC) errorlevel -302 ; Get rid of Bank0 warning ; ; variable definitions, don't need banksel in common address space ; W_Temp equ 0x70 ; Save W during interrupts Status_Temp equ 0x71 ; Save Status during interrupts ByteCounter equ 0x72 Flags equ 0x74 ; Flags Last_SPI equ 0 ; Set when about to send last SPI ; I/O RFID_READY equ 0 ; Transmit RFID data over the SPI line ; ; bit definitions ; SetBaudRate equ 0x81 ; Ox81=129 => 20e6/(16(129+1)) = 9600 LastRFIDByte equ 0x0E ; 14th byte received OutputPortsA equ b'11111000' ; Ports A0-A2 will be outputs ; ;Tables ; RFID0 equ 0x20 RFID1 equ 0x21 RFID2 equ 0x22 RFID3 equ 0x23 RFID4 equ 0x24 RFID5 equ 0x25 RFID6 equ 0x26 RFID7 equ 0x27 RFID8 equ 0x28 RFID9 equ 0x29 RFID10 equ 0x2A RFID11 equ 0x2B RFID12 equ 0x2C RFID13 equ 0x2D org 0 GOTO Main org 4 GOTO IntResponse org 5 EndTbl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Main: ; Run Initialization Routine Initialize: BANKSEL ANSEL ; Set all analog bits to digital CLRF ANSEL CLRF ANSELH BANKSEL TRISA ; Set output ports ;MOVLW OutputPortsA ;ANDWF TRISA,f BCF TRISA,RFID_READY ; Regular I/O BANKSEL PORTA ; Initialize port values CLRF PORTA ; Clear all outputs, including RFID_RDY ; SCI (probably not needed) BANKSEL TRISB BSF TRISB,4 ; SDI: Input BSF TRISB,6 ; SCK: Input (from Master) BANKSEL TRISC BSF TRISC,6 ; SS: Input BCF TRISC,7 ; SDO: Output ; EUSART (probably not needed) BANKSEL TRISB BSF TRISB,5 ; RX: Input BCF TRISB,7 ; TX: Output ; Configure EUSART InitEusart: BANKSEL TXSTA BCF TXSTA,SYNC ; Enable asynchronous serial transmission port BSF TXSTA,TXEN ; Enable transmissions BCF TXSTA,TX9 ; 8-bit transmit BSF TXSTA, BRGH BANKSEL RCSTA BSF RCSTA,SPEN ; Enable asynchronous serial reception port BSF RCSTA,CREN ; Enable receptions BCF RCSTA,RX9 ; 8-bit receive BANKSEL SPBRG ; Set baud rate to 9600 MOVLW SetBaudRate MOVWF SPBRG CLRF SPBRGH ; Configure SPI InitSPI: BANKSEL SSPCON MOVLW b'00110100' MOVWF SSPCON ; 0xxxxxxx = No write collision detect ; x0xxxxxx = No receive overflow indicator ; xx1xxxxx = Enable serial port, SCK, SDO, SDI as serial pins ; xxx1xxxx = Clock idles high ; xxxx0100 = SPI Slave, clock = SCK, SS pin control enabled BANKSEL SSPSTAT MOVLW b'00000000' MOVWF SSPSTAT ; 0xxxxxxx = Data sampled in middle of output ; x0xxxxxx = Data transmitted on falling edge of SCK ; xxXXXXXX = Read only BCF Flags,Last_SPI ; Not waiting to send our last SPI message ; Configure Interrupts InitInterrupts: BANKSEL PIE1 BSF PIE1,RCIE ; EUSART from RFID BSF PIE1,SSPIE ; SPI from Security PIC BANKSEL INTCON BSF INTCON,PEIE ; Peripheral BSF INTCON,GIE ; Global ; Initialize Variables InitVariables: CLRF ByteCounter ; Byte counter is 0 ; Start endless loop while you wait for interrupts Loop: GOTO Loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Functions;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Determine what interrupt was triggered and route to handling function IntResponse: MOVWF W_Temp ; Save W while in interrupt, accessible from any bank SWAPF STATUS,W ; Swap STATUS nibbles and send to W MOVWF Status_Temp ; Save STATUS while in interrupt, accessible from any bank BANKSEL PIR1 BTFSC PIR1,SSPIF ; Check if we had an SPI message GOTO SPIResponse BTFSC PIR1,RCIF ; Check if we had a EUSART message GOTO EusartResponse GOTO IntDone ; Error if this happens ; SPI Response: send out RFID message SPIResponse: BANKSEL SSPBUF MOVF SSPBUF,W ; Probably not needed BANKSEL PIR1 BCF PIR1,SSPIF ; Clear SSPIF in software BTFSC Flags,Last_SPI ; GOTO LastSPI ; Last time, so we shouldn't load in more values GOTO NormalSPI ; Middle time, just load in one value ; Regular RFID send, so send byte while loading in next byte NormalSPI: MOVLW 0x20 ; Start of RFID Table ADDWF ByteCounter,W ; Increment RFID Table by number of bytes we are at MOVWF FSR ; W = 0x20 + ByteCounter MOVF INDF,W ; Load in the byte MOVWF SSPBUF ; Send it out next time through INCF ByteCounter,F ; Increment byte MOVLW LastRFIDByte XORWF ByteCounter,W ; Check if you sent out the last byte BTFSC STATUS,Z BSF Flags,Last_SPI ; If loaded in last RFID byte, set flag GOTO IntDone ; Last RFID send, so get ready for RFID receive, don't load SSPBUF LastSPI: CLRF ByteCounter ; If it is, done with message, so reset the ByteCounter BCF Flags,Last_SPI ; Done with last RFID send BANKSEL PORTA BCF PORTA,RFID_READY; Get ready for next RFID message send GOTO IntDone ; A EUSART message from the RFID was received EusartResponse: MOVLW 0x20 ; Start of RFID Table ADDWF ByteCounter,W ; Increment RFID Table by number of bytes we are at MOVWF FSR ; W = 0x20 + ByteCounter, load pointer BANKSEL RCREG MOVF RCREG,W ; Take the Recieved Byte and move it to the RFID Table MOVWF INDF ; Should clear RCIF INCF ByteCounter,F ; Increment Byte Recieved MOVLW LastRFIDByte XORWF ByteCounter,W ; Check if you got the last byte BTFSC STATUS,Z CALL Last_EUSART ; GOTO IntDone ; Got our last EUSART message Last_EUSART: CLRF ByteCounter ; If it is, done with message, so reset the ByteCounter BANKSEL SSPBUF MOVF SSPBUF,W ; Probably not needed BANKSEL PIR1 BCF PIR1,SSPIF ; Clear SSPIF in software ; Preload the buffer so we can auto-send data when we get an SPI interrupt MOVLW 0x20 ; Start of RFID Table ADDWF ByteCounter,W ; Increment RFID Table by number of bytes we are at MOVWF FSR ; W = 0x20 + ByteCounter MOVF INDF,W ; Load in the byte INCF ByteCounter,F ; Increment Byte Received BANKSEL PORTA BSF PORTA,RFID_READY; Tell Master PIC we are read to send RFID message RETURN ; Exit interrupt response IntDone: SWAPF Status_Temp,W ; Swap nibbles in Status_Temp again and move to W MOVWF STATUS ; Restore status SWAPF W_Temp,F ; Swap nibbles in W_Temp and overwrite the file SWAPF W_Temp,W ; Swap nibbles in W_Temp and save in W RETFIE ; Return and re-enable interrupts END