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
MCP2515.cpp
- Committer:
- FalconOnishi
- Date:
- 2013-01-18
- Revision:
- 0:b65cb1bbf0ce
File content as of revision 0:b65cb1bbf0ce:
#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)); }