Transplantation from Arduino MCP2515 Library which is made by Kyle Crockett. http://code.google.com/p/canduino/source/browse/trunk/Library/CAN/CAN.h?r=24

Dependents:   DISCO-F746NG_rtos_test

Files at this revision

API Documentation at this revision

Comitter:
FalconOnishi
Date:
Fri Jan 18 17:00:28 2013 +0000
Commit message:
Add some utility methods

Changed in this revision

MCP2515.cpp Show annotated file Show diff for this revision Revisions of this file
MCP2515.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP2515.cpp	Fri Jan 18 17:00:28 2013 +0000
@@ -0,0 +1,474 @@
+
+#include "MCP2515.h"
+
+MCP2515::MCP2515(SPI& spi, PinName cs) : spi(spi), cs(cs)
+{
+    /*
+    reset = 0; // RESET MCP2515 CONTROLLER
+    wait_ms(10);
+    reset = 1;
+    wait_ms(100);
+    */
+}
+
+void MCP2515::baudConfig(int bitRate)//sets bitrate for MCP2515 node
+{
+    byte config0 = 0x00;
+    byte config1 = 0x00;
+    byte config2 = 0x00;
+
+    switch (bitRate)
+    {
+case 10:
+        config0 = 0x31;
+        config1 = 0xB8;
+        config2 = 0x05;
+        break;
+
+case 20:
+        config0 = 0x18;
+        config1 = 0xB8;
+        config2 = 0x05;
+        break;
+
+case 50:
+        config0 = 0x09;
+        config1 = 0xB8;
+        config2 = 0x05;
+        break;
+
+case 100:
+        config0 = 0x04;
+        config1 = 0xB8;
+        config2 = 0x05;
+        break;
+
+case 125:
+        config0 = 0x03;
+        config1 = 0xB8;
+        config2 = 0x05;
+        break;
+
+case 250:
+        config0 = 0x01;
+        config1 = 0xB8;
+        config2 = 0x05;
+        break;
+
+case 500:
+        config0 = 0x00;
+        config1 = 0xB8;
+        config2 = 0x05;
+        break;
+case 1000:
+    //1 megabit mode added by Patrick Cruce(pcruce_at_igpp.ucla.edu)
+    //Faster communications enabled by shortening bit timing phases(3 Tq. PS1 & 3 Tq. PS2) Note that this may exacerbate errors due to synchronization or arbitration.
+    config0 = 0x80;
+    config1 = 0x90;
+    config2 = 0x02;
+    }
+    cs = 0;
+    wait_ms(10);
+    spi.write(WRITE);
+    spi.write(CNF0);
+    spi.write(config0);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+
+    cs = 0;
+    wait_ms(10);
+    spi.write(WRITE);
+    spi.write(CNF1);
+    spi.write(config1);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+
+    cs = 0;
+    wait_ms(10);
+    spi.write(WRITE);
+    spi.write(CNF2);
+    spi.write(config2);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+}
+
+//Method added to enable testing in loopback mode.(pcruce_at_igpp.ucla.edu)
+void MCP2515::setMode(MCP2515Mode mode) { //put MCP2515 controller in one of five modes
+
+    //byte writeVal,mask,readVal;
+    byte writeVal = 0x00;
+    byte mask = 0x00;
+
+    switch(mode) {
+      case CONFIGURATION:
+            writeVal = 0x80;
+            break;
+      case NORMAL:
+          writeVal = 0x00;
+            break;
+      case SLEEP:
+            writeVal = 0x20;
+          break;
+    case LISTEN:
+            writeVal = 0x60;
+          break;
+      case LOOPBACK:
+            writeVal = 0x40;
+          break;
+   }
+
+    mask = 0xE0;
+
+    cs = 0;
+    spi.write(BIT_MODIFY);
+    spi.write(MCP2515CTRL);
+    spi.write(mask);
+    spi.write(writeVal);
+    cs = 1;
+
+}
+
+
+void MCP2515::send_0()//transmits buffer 0
+{
+
+    //wait_mss removed from SEND command(pcruce_at_igpp.ucla.edu)
+    //In testing we found that any lost data was from PC<->Serial wait_mss,
+    //Not MCP2515 Controller/AVR wait_mss.  Thus removing the wait_mss at this level
+    //allows maximum flexibility and performance.
+    cs = 0;
+    spi.write(SEND_TX_BUF_0);
+    cs = 1;
+}
+
+void MCP2515::send_1()//transmits buffer 1
+{
+    cs = 0;
+    spi.write(SEND_TX_BUF_1);
+    cs = 1;
+}
+
+void MCP2515::send_2()//transmits buffer 2
+{
+    cs = 0;
+    spi.write(SEND_TX_BUF_2);
+    cs = 1;
+}
+
+char MCP2515::readID_0()//reads ID in recieve buffer 0
+{
+    char retVal;
+    cs = 0;
+    wait_ms(10);
+    spi.write(READ_RX_BUF_0_ID);
+    retVal = spi.write(0xFF);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+    return retVal;
+}
+
+char MCP2515::readID_1()//reads ID in reciever buffer 1
+{
+    char retVal;
+    cs = 0;
+    wait_ms(10);
+    spi.write(READ_RX_BUF_1_ID);
+    retVal = spi.write(0xFF);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+    return retVal;
+}
+
+char MCP2515::readDATA_0()//reads DATA in recieve buffer 0
+{
+    char retVal;
+    cs = 0;
+    wait_ms(10);
+    spi.write( READ_RX_BUF_0_DATA);
+    retVal = spi.write(0xFF);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+    return retVal;
+}
+
+char MCP2515::readDATA_1()//reads data in recieve buffer 1
+{
+    char retVal;
+    cs = 0;
+    wait_ms(10);
+    spi.write( READ_RX_BUF_1_DATA);
+    retVal = spi.write(0xFF);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+    return retVal;
+}
+
+    //extending MCP2515 data read to full frames(pcruce_at_igpp.ucla.edu)
+    //It is the responsibility of the user to allocate memory for output.
+    //If you don't know what length the bus frames will be, data_out should be 8-bytes
+void MCP2515::readDATA_ff_0(byte* length_out,byte *data_out,unsigned short *id_out){
+
+    byte len,i;
+    unsigned short id_h,id_l;
+
+    cs = 0;
+    spi.write(READ_RX_BUF_0_ID);
+    id_h = (unsigned short) spi.write(0xFF); //id high
+    id_l = (unsigned short) spi.write(0xFF); //id low
+    spi.write(0xFF); //extended id high(unused)
+    spi.write(0xFF); //extended id low(unused)
+    len = (spi.write(0xFF) & 0x0F); //data length code
+    for (i = 0;i<len;i++) {
+        data_out[i] = spi.write(0xFF);
+    }
+    cs = 1;
+    (*length_out) = len;
+    (*id_out) = ((id_h << 3) + ((id_l & 0xE0) >> 5)); //repack identifier
+    
+}
+
+void MCP2515::readDATA_ff_1(byte* length_out,byte *data_out,unsigned short *id_out){
+
+    byte id_h,id_l,len,i;
+
+    cs = 0;
+    spi.write(READ_RX_BUF_1_ID);
+    id_h = spi.write(0xFF); //id high
+    id_l = spi.write(0xFF); //id low
+    spi.write(0xFF); //extended id high(unused)
+    spi.write(0xFF); //extended id low(unused)
+    len = (spi.write(0xFF) & 0x0F); //data length code
+    for (i = 0;i<len;i++) {
+        data_out[i] = spi.write(0xFF);
+    }
+    cs = 1;
+
+    (*length_out) = len;
+    (*id_out) = ((((unsigned short) id_h) << 3) + ((id_l & 0xE0) >> 5)); //repack identifier
+}
+
+    //Adding method to read status register
+    //MCP2515 be used to determine whether a frame was received.
+    //(readStatus() & 0x80) == 0x80 means frame in buffer 0
+    //(readStatus() & 0x40) == 0x40 means frame in buffer 1
+byte MCP2515::readStatus() 
+{
+    byte retVal;
+    cs = 0;
+    spi.write(READ_STATUS);
+    retVal = spi.write(0xFF);
+    cs = 1;
+    return retVal;
+
+}
+
+void MCP2515::load_0(byte identifier, byte data)//loads ID and DATA into transmit buffer 0
+{
+    cs = 0;
+    wait_ms(10);
+    spi.write(LOAD_TX_BUF_0_ID);
+    spi.write(identifier);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+
+    cs = 0;
+    wait_ms(10);
+    spi.write(LOAD_TX_BUF_0_DATA);
+    spi.write(data);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+}
+
+void MCP2515::load_1(byte identifier, byte data)//loads ID and DATA into transmit buffer 1
+{
+    cs = 0;
+    wait_ms(10);
+    spi.write(LOAD_TX_BUF_1_ID);
+    spi.write(identifier);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+
+    cs = 0;
+    wait_ms(10);
+    spi.write(LOAD_TX_BUF_1_DATA);
+    spi.write(data);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+}
+
+void MCP2515::load_2(byte identifier, byte data)//loads ID and DATA into transmit buffer 2
+{
+    cs = 0;
+    wait_ms(10);
+    spi.write(LOAD_TX_BUF_2_ID);
+    spi.write(identifier);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+
+    cs = 0;
+    wait_ms(10);
+    spi.write(LOAD_TX_BUF_2_DATA);
+    spi.write(data);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+}
+
+void MCP2515::load_ff_0(byte length,unsigned short identifier,byte *data)
+{
+    
+    byte i,id_high,id_low;
+
+    //generate id bytes before spi write
+    id_high = (byte) (identifier >> 3);
+    id_low = (byte) ((identifier << 5) & 0x00E0);
+
+    cs = 0;
+    spi.write(LOAD_TX_BUF_0_ID);
+    spi.write(id_high); //identifier high bits
+    spi.write(id_low); //identifier low bits
+    spi.write(0x00); //extended identifier registers(unused)
+    spi.write(0x00);
+    spi.write(length);
+    for (i=0;i<length;i++) { //load data buffer
+        spi.write(data[i]);
+    }
+
+    cs = 1;
+
+}
+
+void MCP2515::load_ff_1(byte length,unsigned short identifier,byte *data)
+{
+    
+    byte i,id_high,id_low;
+
+    //generate id bytes before spi write
+    id_high = (byte) (identifier >> 3);
+    id_low = (byte) ((identifier << 5) & 0x00E0);
+
+    cs = 0;
+    spi.write(LOAD_TX_BUF_1_ID);
+    spi.write(id_high); //identifier high bits
+    spi.write(id_low); //identifier low bits
+    spi.write(0x00); //extended identifier registers(unused)
+    spi.write(0x00);
+    spi.write(length);
+    for (i=0;i<length;i++) { //load data buffer
+        spi.write(data[i]);
+    }
+
+    cs = 1;
+
+
+}
+
+void MCP2515::load_ff_2(byte length,unsigned short identifier,byte *data)
+{
+    
+    byte i,id_high,id_low;
+
+    //generate id bytes before spi write
+    id_high = (byte) (identifier >> 3);
+    id_low = (byte) ((identifier << 5) & 0x00E0);
+
+    cs = 0;
+
+    spi.write(LOAD_TX_BUF_2_ID);
+    spi.write(id_high); //identifier high bits
+    spi.write(id_low); //identifier low bits
+    spi.write(0x00); //extended identifier registers(unused)
+    spi.write(0x00);
+    spi.write(length); //data length code
+    for (i=0;i<length;i++) { //load data buffer
+        spi.write(data[i]);
+    }
+
+    cs = 1;
+
+}
+
+//------------------------------------------------------------------------------
+//Added for ram
+void MCP2515::writeRegister(byte address, byte data)
+{
+    cs = 0;
+    wait_ms(10);
+    spi.write(WRITE);
+    spi.write(address);
+    spi.write(data);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+}
+void MCP2515::readRegister(byte address, byte *data_out)
+{
+    cs = 0;
+    wait_ms(10);
+    spi.write(READ);
+    spi.write(address);
+    *data_out = spi.write(0xFF);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+}
+
+void MCP2515::reset()
+{
+    cs = 0;
+    wait_ms(10);
+    spi.write(RESET_REG);
+    wait_ms(10);
+    cs = 1;
+    wait_ms(10);
+}
+
+byte MCP2515::readRXStatus()
+{
+    byte retVal;
+    cs = 0;
+    spi.write(RX_STATUS);
+    retVal = spi.write(0xFF);
+    cs = 1;
+    return retVal;
+}
+
+void MCP2515::bitModify(byte address, byte mask, byte data)
+{
+    cs = 0;
+    spi.write(BIT_MODIFY);
+    spi.write(address);
+    spi.write(mask);
+    spi.write(data);
+    cs = 1;
+}
+
+void MCP2515::setMask(unsigned short identifier)
+{
+    setMask_0(identifier);
+    setMask_1(identifier);
+}
+
+void MCP2515::setMask_0(unsigned short identifier)
+{
+    writeRegister(RXM0SIDH, (byte)(identifier>>3));
+    writeRegister(RXM0SIDL, (byte)(identifier<<5));
+}
+
+void MCP2515::setMask_1(unsigned short identifier)
+{
+    writeRegister(RXM1SIDH, (byte)(identifier>>3));
+    writeRegister(RXM1SIDL, (byte)(identifier<<5));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP2515.h	Fri Jan 18 17:00:28 2013 +0000
@@ -0,0 +1,268 @@
+#include "mbed.h"
+
+/*
+Created by: Kyle Crockett
+For MCP2515duino with 16MHz oscillator.
+CNFx register values.
+use preprocessor command "_XXkbps" 
+"XX" is the baud rate.
+
+10 kbps
+CNF1/BRGCON1    b'00110001'     0x31
+CNF2/BRGCON2    b'10111000'     0xB8
+CNF3/BRGCON3    b'00000101'     0x05
+
+20 kbps
+CNF1/BRGCON1    b'00011000'     0x18
+CNF2/BRGCON2    b'10111000'     0xB8
+CNF3/BRGCON3    b'00000101'     0x05
+
+50 kbps
+CNF1/BRGCON1    b'00001001'     0x09
+CNF2/BRGCON2    b'10111000'     0xB8
+CNF3/BRGCON3    b'00000101'     0x05
+
+100 kbps
+CNF1/BRGCON1    b'00000100'     0x04
+CNF2/BRGCON2    b'10111000'     0xB8
+CNF3/BRGCON3    b'00000101'     0x05
+
+125 kbps
+CNF1/BRGCON1    b'00000011'     0x03
+CNF2/BRGCON2    b'10111000'     0xB8
+CNF3/BRGCON3    b'00000101'     0x05
+
+250 kbps
+CNF1/BRGCON1    b'00000001'     0x01
+CNF2/BRGCON2    b'10111000'     0xB8
+CNF3/BRGCON3    b'00000101'     0x05
+
+500 kbps
+CNF1/BRGCON1    b'00000000'     0x00
+CNF2/BRGCON2    b'10111000'     0xB8
+CNF3/BRGCON3    b'00000101'     0x05
+
+800 kbps
+Not yet supported
+
+1000 kbps
+Settings added by Patrick Cruce(pcruce_at_igpp.ucla.edu)
+CNF1=b'10000000'=0x80 = SJW = 3 Tq. & BRP = 0
+CNF2=b'10010000'=0x90 = BLTMode = 1 & SAM = 0 & PS1 = 3 & PR = 1
+CNF3=b'00000010'=0x02 = SOF = 0  & WAKFIL = 0 & PS2 = 3
+
+*/
+#ifndef MCP2515_h
+#define MCP2515_h
+
+#define SCK 13 //spi
+#define MISO 12
+#define MOSI 11
+#define SS 10
+#define RESET 2//reset pin
+
+#define RESET_REG 0xc0  
+#define READ 0x03 
+#define WRITE 0x02 //read and write comands for SPI
+
+#define READ_RX_BUF_0_ID 0x90
+#define READ_RX_BUF_0_DATA 0x92
+#define READ_RX_BUF_1_ID 0x94
+#define READ_RX_BUF_1_DATA 0x96 //SPI commands for reading MCP2515 RX buffers
+
+#define LOAD_TX_BUF_0_ID 0x40
+#define LOAD_TX_BUF_0_DATA 0x41
+#define LOAD_TX_BUF_1_ID 0x42
+#define LOAD_TX_BUF_1_DATA 0x43
+#define LOAD_TX_BUF_2_ID 0x44
+#define LOAD_TX_BUF_2_DATA 0x45 //SPI commands for loading MCP2515 TX buffers
+
+#define SEND_TX_BUF_0 0x81
+#define SEND_TX_BUF_1 0x82
+#define SEND_TX_BUF_2 0x83 //SPI commands for transmitting MCP2515 TX buffers
+
+#define READ_STATUS 0xA0
+#define RX_STATUS 0xB0
+#define BIT_MODIFY 0x05 //Other commands
+
+
+//Registers
+#define CNF0 0x2A
+#define CNF1 0x29
+#define CNF2 0x28
+#define TXB0CTRL 0x30 
+#define TXB1CTRL 0x40
+#define TXB2CTRL 0x50 //TRANSMIT BUFFER CONTROL REGISTER
+#define TXB0DLC 0x35 //Data length code registers
+#define TXB1DLC 0x45
+#define TXB2DLC 0x55
+#define MCP2515CTRL 0x0F //Mode control register
+#define MCP2515STAT 0x0E //Mode status register
+
+//------------------------------------------------------------------------------
+//Added for ram
+// Register Bit Masks
+// MCP2515STAT
+#define MODE_CONFIG     0x80
+#define MODE_LISTEN     0x60
+#define MODE_LOOPBACK   0x40
+#define MODE_SLEEP      0x20
+#define MODE_NORMAL     0x00
+
+//MCP2515 bus error counter
+#define TEC            0x1C
+#define REC            0x1D
+
+//Mask 0
+#define RXM0SIDH    0x20 //Mask0 normal ID high
+#define RXM0SIDL    0x21 //Mask0 normal ID low
+#define RXM0EID8    0x22 //Mask0 extended ID high
+#define RXM0EID0    0x23 //Mask0 extended ID low
+
+//Mask 1
+#define RXM1SIDH    0x24 //Mask1 normal ID high
+#define RXM1SIDL    0x25 //Mask1 normal ID low
+#define RXM1EID8    0x26 //Mask1 extended ID high
+#define RXM1EID0    0x27 //Mask1 extended ID low
+
+#define MCP2515INTE        0x2B //Interept permission
+#define MCP2515INTF        0x2C //Interept flag
+#define EFLG        0x2D //Error flag
+
+#define MASK_SID_ALL_HIT   0x0000 //Mask all
+#define MASK_SID_CPL_MATCH 0x07FF //Disable mask
+
+
+#define MCP2515_RTS         0x80
+#define MCP2515_READ_BUFFER 0x90
+#define MCP2515_LOAD_BUFFER 0X40
+
+//..............................................................................
+//test
+// MCP2515INTF
+#define RX0IF           0x01
+#define RX1IF           0x02
+#define TX0IF           0x04
+#define TX1IF           0x08
+#define TX2IF           0x10
+#define ERRIF           0x20
+#define WAKIF           0x40
+#define MERRF           0x80
+
+// Configuration Registers
+#define BFPCTRL         0x0C
+#define TXRTSCTRL       0x0D
+
+// TX Buffer 0
+#define TXB0CTRL        0x30
+#define TXB0SIDH        0x31
+#define TXB0SIDL        0x32
+#define TXB0EID8        0x33
+#define TXB0EID0        0x34
+#define TXB0DLC         0x35
+
+// TX Buffer 1
+#define TXB1CTRL        0x40
+#define TXB1SIDH        0x41
+#define TXB1SIDL        0x42
+#define TXB1EID8        0x43
+#define TXB1EID0        0x44
+#define TXB1DLC         0x45
+
+// TX Buffer 2
+#define TXB2CTRL        0x50
+#define TXB2SIDH        0x51
+#define TXB2SIDL        0x52
+#define TXB2EID8        0x53
+#define TXB2EID0        0x54
+#define TXB2DLC         0x55
+
+// RX Buffer 0
+#define RXB0CTRL        0x60
+#define RXB0SIDH        0x61
+#define RXB0SIDL        0x62
+#define RXB0EID8        0x63
+#define RXB0EID0        0x64
+#define RXB0DLC         0x65
+
+// RX Buffer 1
+#define RXB1CTRL        0x70
+#define RXB1SIDH        0x71
+#define RXB1SIDL        0x72
+#define RXB1EID8        0x73
+#define RXB1EID0        0x74
+#define RXB1DLC         0x75
+
+// Buffer Bit Masks
+#define RXB0            0x00
+#define RXB1            0x02
+#define TXB0            0x01
+#define TXB1            0x02
+#define TXB2            0x04
+#define TXB_ALL                  TXB0 | TXB1 | TXB2
+
+#define RXB_RX_STDEXT   0x00
+#define RXB_RX_MASK     0x60
+#define RXB_BUKT_MASK   (1<<2)
+
+typedef unsigned char byte;
+
+enum MCP2515Mode {CONFIGURATION,NORMAL,SLEEP,LISTEN,LOOPBACK};
+
+class MCP2515
+{
+public:
+    MCP2515(SPI& spi, PinName cs);
+    //void begin();//sets up MCP2515
+    void baudConfig(int bitRate);//sets up baud
+
+    //Method added to enable testing in loopback mode.(pcruce_at_igpp.ucla.edu)
+    void setMode(MCP2515Mode mode) ;//put MCP2515 controller in one of five modes
+
+    void send_0();//request to transmit buffer X
+    void send_1();
+    void send_2();
+
+    char readID_0();//read ID/DATA of recieve buffer X
+    char readID_1();
+
+    char readDATA_0();
+    char readDATA_1();
+
+    //extending MCP2515 data read to full frames(pcruce_at_igpp.ucla.edu)
+    //data_out should be array of 8-bytes or frame length.
+    void readDATA_ff_0(byte* length_out,byte *data_out,unsigned short *id_out);
+    void readDATA_ff_1(byte* length_out,byte *data_out,unsigned short *id_out);
+
+    //Adding MCP2515 to read status register(pcruce_at_igpp.ucla.edu)
+    //MCP2515 be used to determine whether a frame was received.
+    //(readStatus() & 0x80) == 0x80 means frame in buffer 0
+    //(readStatus() & 0x40) == 0x40 means frame in buffer 1
+    byte readStatus();
+
+    void load_0(byte identifier, byte data);//load transmit buffer X
+    void load_1(byte identifier, byte data);
+    void load_2(byte identifier, byte data);
+
+    //extending MCP2515 write to full frame(pcruce_at_igpp.ucla.edu)
+    //Identifier should be a value between 0 and 2^11-1, longer identifiers will be truncated(ie does not support extended frames)
+    void load_ff_0(byte length,unsigned short identifier,byte *data);
+    void load_ff_1(byte length,unsigned short identifier,byte *data);
+    void load_ff_2(byte length,unsigned short identifier,byte *data);
+    
+    //--------------------------------------------------------------------------
+    //Added for ram
+    void writeRegister(byte address, byte data);
+    void readRegister(byte address, byte *data_out);
+    void reset();
+    byte readRXStatus();
+    void bitModify(byte address, byte mask, byte data);
+    void setMask(unsigned short identifier);
+    void setMask_0(unsigned short identifier);
+    void setMask_1(unsigned short identifier);
+private:
+    DigitalOut cs;
+    SPI &spi;  
+};
+
+#endif