Opto-isolated CAN-Node with a pic and the MCP2510

Name: Mr. Benoit LEDUC
Company: Instrumentation DIFRA
Web Site: http://www.difra.be
Medical products ORL

Schematic :

Firmware :

;************************************************************
; FILE   : spifile.asm
; DATE  : 21-aug-2002
; Author : Benoît LEDUC
; PRODUCT : General use for SPI
; COPYRIGHT : Instrumentation DIFRA s.a.
; Descr. : This module contain the functions to control the Bus SPI
; Version : V1.0 (BL)
;************************************************************
;************************************************************
; gestSPI - envoi et reception des donnees SPI
;  Usage  : SPI
; Parameters : in W
;  Return value :  in W
;  Notes  :  
;------------------------------------------------------------
gestSPI BANK0
 movwf SSPBUF  ; envoi de la donnee sur SPI
jattSPI BANK1
 btfss SSPSTAT, BF ; Wait until BF=0
 goto jattSPI  ; de la transmission
 bcf     SSPSTAT, BF ; if(BF) BF=0
 BANK0
 movf SSPBUF,W 
 return
;
;************************LOCAL MACRO*************************
; idleLOW - Data transmitted on falling edge of SCK
;  Usage  : SPI
; Parameters : no
;  Return value : no
;  Notes  :  
;------------------------------------------------------------
idleLOW bcf SSPCON,SSPEN ; Reconfiguration Port SPI
 bcf SSPCON,CKP ; Data transmitted on falling edge of SCK
 bsf SSPCON,SSPEN
 return
;
;************************LOCAL MACRO*************************
; idleHIGH - Data transmitted on rising edge of SCK
;  Usage  : SPI
; Parameters : no
;  Return value : no
;  Notes  :  
;------------------------------------------------------------
idleHIGH bcf SSPCON,SSPEN ; Reconfiguration Port SPI
 bsf SSPCON,CKP ; Data transmitted on rising edge of SCK
 bsf SSPCON,SSPEN
 return
;
;************************************************************
;************************************************************
; FILE   : canfile.asm
; DATE  : 12-juli-2002
; Author : Benoît LEDUC
; PRODUCT : MCP2510 CAN Interface Module with SPI interface
; COPYRIGHT : Instrumentation DIFRA s.a.
; Descr. : This module contain the functions to control the can BUS
; Version : V2.0 (BL)
; Use : #define CLKOUT and BITRATE in main program
;************************************************************
; MCP2510 Instructions
#define d2510Rd       H'03'       ; MCP2510 read instruction
#define d2510Wrt      H'02'       ; MCP2510 write instruction
#define d2510Reset    H'C0'       ; MCP2510 reset instruction
#define d2510RTS      H'80'       ; MCP2510 RTS instruction
#define d2510Status   H'A0'       ; MCP2510 Status instruction
#define d2510BitMod   H'05'       ; MCP2510 bit modify instruction
;****************CAN BUS BITRATE CONFIGURATION***************
#define BITRATE1M H'00'  ; 1MHz CAN BUS Configuration
#define BITRATE500K H'01'  ; 500kHz CAN BUS Configuration
#define BITRATE125K H'07'  ; 125kHz CAN BUS Configuration
;
#define PRESCALER1 H'00'  ; CLKOUT = 16MHZ
#define PRESCALER2 H'01'  ; CLKOUT = 8MHZ
#define PRESCALER4 H'02'  ; CLKOUT = 4MHZ
#define PRESCALER8 H'03'  ; CLKOUT = 2MHZ
;**********************************************************
;*************** SPECIAL CAN MACROS ***********************
; Read 2510 register Reg and return data in W.
MCP_ReadL MACRO REG
  bcf tp2510_CS_
  movlw d2510Rd
  call gestSPI
  movlw REG
  call gestSPI 
  clrw
  call gestSPI 
  bsf tp2510_CS_
           ENDM
;
MCP_ReadV MACRO REG
  bcf tp2510_CS_
  movlw d2510Rd
  call gestSPI
  movf REG, W
  call gestSPI 
  clrw
  call gestSPI 
  bsf tp2510_CS_
           ENDM
;
; Write literal byte to 2510 register Reg.
MCP_WriteL MACRO REG, LDATA
           bcf   tp2510_CS_            ; CS_ for 2510 chip
  movlw d2510Wrt
  call gestSPI
  movlw REG
  call gestSPI 
  movlw LDATA
  call gestSPI 
  bsf tp2510_CS_
  ENDM
;
; Write Data byte to 2510 register Reg.
MCP_WriteV  MACRO  REG, VDATA
  bcf   tp2510_CS_            ; CS_ for 2510 chip
  movlw d2510Wrt
  call gestSPI
  movlw REG
  call gestSPI 
  movf VDATA, W
  call gestSPI 
  bsf tp2510_CS_
  ENDM
;
; Write W byte to 2510 register Reg.
MCP_WriteW  MACRO REG
  movwf pWork
  bcf   tp2510_CS_            ; CS_ for 2510 chip
  movlw d2510Wrt
  call gestSPI
  movlw REG
  call gestSPI 
  movf pWork, W
  call gestSPI
           ENDM
;
; Write bits determined by Mask & Data to 2510 register Reg.
MCP_BitMod  MACRO REG, MASK, DATA
  bcf tp2510_CS_
  movlw d2510BitMod
  call gestSPI  
  movlw REG
  call gestSPI
  movlw MASK
  call gestSPI
  movlw DATA
  call gestSPI
  bsf tp2510_CS_
  ENDM
;
; Arm xmit buffers for xmission
MCP_Rts  MACRO  DATA
  bcf tp2510_CS_
  movlw   d2510RTS             ; MCP2510 RTS instruction
         iorlw   DATA       ; get data and OR it with RTS
  call gestSPI
  bsf tp2510_CS_
           ENDM
;
;************************************************************
; mcpReset - RESET
;  Usage  :  
;   : 
; Parameters : no
;  Return value : no
;  Notes  :  
;------------------------------------------------------------
Mcp_Reset MACRO
  bcf tp2510_CS_
  nop
  movlw d2510Reset
  call gestSPI
  nop
  bsf  tp2510_CS_
  ENDM
;
;********************************************************************
; Init2510 - Initialize CAN Controller mcp2510
;  Usage  : start
;  Parameters : no
;  Return value : no
;  Notes  :
;********************************************************************
Init2510
 Mcp_Reset
 MCP_BitMod CANCTRL, b'00000011', CLKOUT
;
 MCP_WriteL CNF1, BITRATE
 MCP_WriteL CNF2, H'90'
 MCP_WriteL CNF3, H'02'
;
 MCP_WriteL RXM0SIDH, H'FF'
 MCP_WriteL RXM0SIDL, H'FF'
 MCP_WriteL RXF0SIDH, H'FF'
 MCP_WriteL RXF0SIDL, H'FF'
 MCP_WriteL RXF1SIDH, H'FF'
 MCP_WriteL RXF1SIDL, H'FF'
;
 MCP_WriteL RXM1SIDH, H'FF'
 MCP_WriteL RXM1SIDL, H'FF'
 MCP_WriteL RXF2SIDH, IDH
 MCP_WriteL RXF2SIDL, IDL
 MCP_WriteL RXF3SIDH, H'FF'
 MCP_WriteL RXF3SIDL, H'FF'
 MCP_WriteL RXF4SIDH, H'FF'
 MCP_WriteL RXF4SIDL, H'FF'
 MCP_WriteL RXF5SIDH, H'FF'
 MCP_WriteL RXF5SIDL, H'FF'
;
 MCP_WriteL CANINTE, b'00000011'   ; Receive Buffer 0 and 1 Full Interrupt Enable
;
;; Set normal mode
 MCP_BitMod CANCTRL, b'11100000', b'00000000' ; REQOP2=REQOP1=REQOP0=0
 MCP_ReadL CANSTAT
 nop
 andlw  0xE0
 btfss  STATUS, Z
 goto  Init2510    ; retry
;
 return
;
;********************************************************************

;*************************** CAN BUS 11 bits ID : 0x0120 = 00000001001_00000 (=9 dec)**************
#define IDH  H'01'
#define IDL  H'20'
#define BITRATE  BITRATE1M   ; 1Mb/s
#define CLKOUT  PRESCALER2   ; CLKOUT = 16MHZ/2 = 8MHZ

#define tp2510_CS_ PORTA, 5   ; CAN Controller CS pin
#define tp_SPICLK_ PORTC, 3   ; SPI Clock
#define tp_SPII_ PORTC, 4   ; SPI In
#define tp_SPIO_ PORTC, 5   ; SPI Out

cblock 0x20
 pWork      ; canfile.asm
 pRxBuf:8     ; canfile.asm
 pTxBuf:8     ; canfile.asm
 bTxCnt      ; canfile.asm
;
endc

;*************************BEGIN PROGRAM CODE*******************************************************
  org   0x00   ; memory @ 0x0
     nop     ; nop ICD
  goto   start   ; Saut du vecteur d'interruption
  org   04h   ; Interrupt Vector @ 0x4
  goto   routint   ; Routine d'interruption
;**************************************************************************************************
#include "SPIFILE.ASM"     ; Use for SPI Interface
#include "CANFILE.ASM"     ; Microchip MCP2510 Can Controller


At initialisation of your program, call :

  BANK0
  bcf  SSPCON, SSPEN  ; disable SPI
  clrf  SSPCON   ; SPI master mode, SCK = Fosc/4
  bsf  SSPCON, CKP  ; Idle High
   BANK1
  bcf  SSPSTAT, SMP
  bcf  SSPSTAT, CKE
  BANK0
  bsf  SSPCON, SSPEN  ; Initialisation des lignes SPI
;

call   Init2510

After, use to send:
  MCP_WriteL TXB0SIDH, IDH
  MCP_WriteL TXB0SIDL, IDL
  MCP_WriteL TXB0DLC, H'01'
  MCP_WriteV TXB0D0, pTxBuf
  MCP_Rts  RTS0
;

and to receive:

jCheck   bcf   STATUS, Z ; clear Z for return
  MCP_ReadL CANINTF
       andlw    0x02     
  btfsc    STATUS, Z
  goto  jLoop
  MCP_ReadL RXB1D0
  movwf  pRxBuf ; Receive Data 0
  MCP_ReadL RXB1D1
  movwf  pRxBuf+1 ; Receive Data 1
...

...

 

Benoit LEDUC, ing.
Electronics Designer
Rue des 22, 9
BELGIUM 4000 Liège
Tel : 042531234
Fax : 027005999
benoit.leduc@tiscali.be