?? can.asm
字號:
;+===========================+
;|John Murphy |
;|Kenneth Heck |
;| |
;|CAN bus adaptor |
;|28 November, 2001 |
;| |
;+===========================+
;****************************
; TO DO
; "_" means TO DO
; "x" means done and tested (But may be breaking another section of code)
; "?" means done, but untested/ not working properly
;----------------------------
; ? Configure 2510 to send interrupt
; ? Receive multiple bytes at a time from the 2510 registers
; _ Detect mode
; ? Put in CF stub functions
;
;****************************
list p=16f877
; Include file, change directory if needed
include "p16f877.inc"
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _WRT_ENABLE_OFF & _LVP_ON & _DEBUG_OFF & _CPD_OFF
#define debug
;#define echo
;+===========================+
;| Variables |
;+===========================+
;For the Interrupt Service Routines:
W_TEMP equ 0x71
STATUS_TEMP equ 0x72
PCLATH_TEMP equ 0x73
FSR_TEMP equ 0x74
;***************************************
; DEVMODE
;Device's Mode/STATUS Byte
; Bit 0-2 MODE SELECT
; Bit 3 PC_buff overflow error
; Bit 4 CAN_buff overflow error
; Bit 5 CompactFlash full error
; Bit 6 PC_buff contains data
;***************************************
DEVMODE equ 0x75
#define PC_BUFF_OVERFLOW DEVMODE, 3
#define CAN_BUFF_OVERFLOW DEVMODE, 4
#define CF_INSERTED DEVMODE, 5
#define PC_BUFF_NOTEMPTY DEVMODE, 6
#define CAN_BUFF_NOTEMPTY DEVMODE, 7
DEVFLAG equ 0x76
#define CAN_RX0_READY DEVFLAG, 0
#define CAN_RX1_READY DEVFLAG, 1
#define SPI_IN_PROGRESS DEVFLAG, 2
#define USART_IN_PROGRESS DEVFLAG, 3
#define CF_IN_PROGRESS DEVFLAG, 4
delay equ 0x21
rcv equ 0x22
loopctr0 equ 0x23
;Whenever we write to the 2510, we write two bytes at a time. Load
;them into these first, then call SPI_Write
; And yes, these are all in the same bank as SSBUF. Makes life much easier later on.
SPI1 equ 0x26
SPI2 equ 0x27
SPI3 equ 0x28
SPIOUT equ 0x29
CF_DATA_HIGH equ 0x2A
CD_DATA_LO equ 0x2B
POWER_ON_MSG equ 0x55
INIT_MSG equ 0x42
;Here are our buffers:
CAN_buff_in equ 0xE5
CAN_buff_out equ 0xE6
CAN_buff_ctr equ 0xE7
PC_buff_in equ 0x33
PC_buff_out equ 0x34
PC_buff_ctr equ 0x35
outcounter equ 0x36
PC_buff equ 0x40 ;This ends at 0x50, for 16 bytes -- two CAN packets' worth
PC_buff_end equ 0x51
CAN_buff equ 0xA0 ;This stretches out to 0xE0h -- 64 bytes
CAN_buff_end equ 0xE1
;+===========================+
;| Constants |
;+===========================+
#define CAN_CS PORTB, 2
#define TXB0_TX PORTB, 6
#define TXB1_TX PORTB, 5
;Compact Flash control lines
#define CF_RESET PORTA, 5 ;Output
#define CF_CD1 PORTA, 1 ;Output
#define CF_OE PORTA, 2 ;Output
#define CF_WE PORTA, 3 ;Output
#define CF_RDY PORTA, 4 ;Input
#define CF_CE1 PORTA, 0 ;Output
;+============================+
; CANSTAT bits 3-1
; Interrupt flag code
; 000 = No Interrupt
; 001 = Error Interrupt
; 010 = Wake Up Interrupt
; 011 = TXB0 Interrupt
; 100 = TXB1 Interrupt
; 101 = TXB2 Interrupt
; 110 = RXB0 Interrupt
; 111 = RXB1 Interrupt
;+============================+
CANCTRL equ 0x0F
CANSTAT equ 0x0E
CANINTE equ 0x2B
CANINTF equ 0x2C
CNF1 equ 0x2A
CNF2 equ 0x29
CNF3 equ 0x28
SPI_RESET equ B'11000000' ;2510's RESET command
RXB0DLC equ 0x65
RXBUF0 equ B'01100110' ;Start of RXB0
RXM0SIDH equ 0x20
RXM0SIDL equ 0x21
RXB1DLC equ 0x75
RXBUF1 equ B'01110110' ;Start of RXB1
RXM1SIDH equ 0x24
RXM1SIDL equ 0x25
TXBUF0 equ B'00100110' ;Start of TXB0
TXBUF1 equ B'01000110' ;Start of TXB1 <- Only one used by current code
TXB1CTRL equ 0x40 ;TXB1 Control Register
TXBUF2 equ B'01010110' ;Start of TXB2
; Start at the reset vector
org 0x000
goto Start
org 0x004
goto IntService
nop
Start
banksel PORTB
clrf PORTB ;Clear PORTB
banksel TRISB
movlw B'01000001' ;PORTB's I/O settings, with an input on RB0/INT
movwf TRISB
movlw B'11000000' ;PORTC's I/O settings
movwf TRISC
movlw 0x00
movwf TRISD ;The data lines for the compact flash card
movwf TRISE
;Address lines for Compact flash are A5-7
; Bit 4 is the CF's reset strobe
movlw B'00010000'
movwf TRISA
; banksel OPTION_REG
; movlw 0xA0
; movwf OPTION_REG
banksel PORTB
movlw B'00000010' ;Turn on Power LED, turn off MCP2510's chip select
movwf PORTB
banksel SPBRG
movlw B'10000001'
movwf SPBRG
banksel TXSTA
movlw B'00100110' ;Enable and active high-speed transmission
movwf TXSTA
banksel RCSTA
clrf RCSTA
movlw B'10010000' ;Enable receive, clear errors
movwf RCSTA
banksel PIE1
bcf PIR1, RCIF
bsf PIE1, RCIE ;RCIE -- interrupt on receive from PC
; bsf PIE1, INTE ;INTE -- external interrupt, from MCP2510
; NOTE: Global Interrupts are NOT enabled HERE
banksel TXREG
movlw POWER_ON_MSG ;ASCII 'B'
movwf TXREG
call txwait
;+===========================+
;| SPI Init |
;+===========================+
;SSPCON is the sync Serial Port Control
; Bits 7 and 6 are Indication/Detection bits set by the PIC
; Bit 5 (Synscronous Seial Port Enable) must be 1 for SPI
; Bit 4 (Clock Polarity) sets the idle state for the CLK
; Bit 3-0 Synchronous Serial Port Select 0000 - 0101 reserved for SPI's
;various speeds
; It looks like, for the sake of safety, we'll be going at 2.5 MHz, or close to it.
banksel SSPCON
movlw B'00110000' ;Currently at 5MHz
banksel SSPSTAT
clrf SSPSTAT
;+==========================+
;| Buffer Config |
;+==========================+
banksel PC_buff
movlw PC_buff
movwf PC_buff_in
movwf PC_buff_out
clrf PC_buff_ctr
movlw 0x00
movwf PC_buff
movwf PC_buff+1
movwf PC_buff+2
movwf PC_buff+3
movwf PC_buff+4
movwf PC_buff+5
movwf PC_buff+6
movwf PC_buff+7
movwf PC_buff+8
movwf PC_buff+9
movwf PC_buff+0xA
movwf PC_buff+0xB
movwf PC_buff+0xC
movwf PC_buff+0xD
movwf PC_buff+0xE
movwf PC_buff+0xF
movwf PC_buff+10
; banksel TXREG
; movlw 0x31
; movwf TXREG
; call txwait
banksel CAN_buff
movlw CAN_buff
movwf CAN_buff_in
movwf CAN_buff_out
clrf CAN_buff_ctr
; banksel TXREG
; movlw 0x30
; movwf TXREG
; call txwait
CF_INIT
;Test and see if there's a card inserted -- don't wait for one to be inserted
; since the directions tell them to insert one before power-up
banksel PORTA
bsf CF_OE
bsf CF_WE
nop ;Propogate signals (> 300 ns)
btfss CF_CD1 ;Is there a card inserted?
goto CAN_INIT ;No? Go set up the 2510
;We have card!
bsf CF_INSERTED
banksel PORTA
bsf CF_RESET
nop
nop
bcf CF_RESET
nop
nop
call wait
call wait
call wait
call wait
call wait
call wait
call wait
call wait
;LONG wait. This may not be long enough, but it's probably OK
;+==========================+
;| MCP2510 Config |
;+==========================+
CAN_INIT
;Initiate MCP2510 reset
banksel PORTB
bcf CAN_CS ;Hit the Chip Select
movlw SPI_RESET
movwf SSPBUF
banksel TXREG
movlw 0x31
movwf TXREG
call txwait
banksel SSPBUF
movfw SSPBUF
banksel PORTB
bsf CAN_CS
; banksel TXREG
; movfw 0x43
; movwf TXREG
;And now -- we wait!
call wait
call wait
call wait
call wait
;This is probably excessive, but time is not
;critical at this point...
; Technically, this should be 128 Osc cycles from the 2510's point of view.
; It's running on the same clock that the PIC is, divided by four
; banksel TXREG
; movlw 0x32
; movwf TXREG
; call txwait
; We need to set up the acceptance masks and filters here.
; For the demo, we're using RXBUF0, so let's set its mask to all 0's
banksel SPI1
movlw RXM0SIDH
movwf SPI1
movlw 0x00
movwf SPI2
call SPI_WRITE
banksel SPI1
movlw RXM0SIDL
movwf SPI1
movlw 0x00
movwf SPI2
call SPI_WRITE
; For that matter, let's turn off RXBUF1 by setting its mask to all 1's,
; ensuring that nothing will match it.
banksel SPI1
movlw RXM1SIDH
movwf SPI1
movlw 0xFF
movwf SPI2
call SPI_WRITE
banksel SPI1
movlw RXM1SIDL
movwf SPI1
movlw 0xFF
movwf SPI2
call SPI_WRITE
;The following settings I got from the sample code that Microchip made available.
banksel SPI1
movlw CNF1
movwf SPI1
movlw 0x03
movwf SPI2
call SPI_WRITE
banksel SPI1
movlw CNF2
movwf SPI1
movlw 0x90
movwf SPI2
call SPI_WRITE
banksel SPI1
movlw CNF3
movwf SPI1
movlw 0x02
movwf SPI2
call SPI_WRITE
; Lastly, let's tell the 2510 to interrupt us upon message receipt in RXB0
banksel SPI1
movlw CANINTE
movwf SPI1
movlw 0x01
movwf SPI2
call SPI_WRITE
;***************************************************************************;
;+ Now that that's all done, let's set it up in loopback mode
;+
;+ banksel SPI1
;+ movlw CANCTRL
;+ movwf SPI1
;+ movlw B'01000000' ; Loopback Mode
;+ movwf SPI2
;+ call SPI_WRITE
;****************************************************************************
banksel SPI1
movlw CANCTRL
movwf SPI1
movlw B'01110000' ; Listen-only mode, and abort all pending transmissions
movwf SPI2
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -