Yoshito Onishi / MCP2515

Dependents:   DISCO-F746NG_rtos_test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCP2515.cpp Source File

MCP2515.cpp

00001 
00002 #include "MCP2515.h"
00003 
00004 MCP2515::MCP2515(SPI& spi, PinName cs) : spi(spi), cs(cs)
00005 {
00006     /*
00007     reset = 0; // RESET MCP2515 CONTROLLER
00008     wait_ms(10);
00009     reset = 1;
00010     wait_ms(100);
00011     */
00012 }
00013 
00014 void MCP2515::baudConfig(int bitRate)//sets bitrate for MCP2515 node
00015 {
00016     byte config0 = 0x00;
00017     byte config1 = 0x00;
00018     byte config2 = 0x00;
00019 
00020     switch (bitRate)
00021     {
00022 case 10:
00023         config0 = 0x31;
00024         config1 = 0xB8;
00025         config2 = 0x05;
00026         break;
00027 
00028 case 20:
00029         config0 = 0x18;
00030         config1 = 0xB8;
00031         config2 = 0x05;
00032         break;
00033 
00034 case 50:
00035         config0 = 0x09;
00036         config1 = 0xB8;
00037         config2 = 0x05;
00038         break;
00039 
00040 case 100:
00041         config0 = 0x04;
00042         config1 = 0xB8;
00043         config2 = 0x05;
00044         break;
00045 
00046 case 125:
00047         config0 = 0x03;
00048         config1 = 0xB8;
00049         config2 = 0x05;
00050         break;
00051 
00052 case 250:
00053         config0 = 0x01;
00054         config1 = 0xB8;
00055         config2 = 0x05;
00056         break;
00057 
00058 case 500:
00059         config0 = 0x00;
00060         config1 = 0xB8;
00061         config2 = 0x05;
00062         break;
00063 case 1000:
00064     //1 megabit mode added by Patrick Cruce(pcruce_at_igpp.ucla.edu)
00065     //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.
00066     config0 = 0x80;
00067     config1 = 0x90;
00068     config2 = 0x02;
00069     }
00070     cs = 0;
00071     wait_ms(10);
00072     spi.write(WRITE);
00073     spi.write(CNF0);
00074     spi.write(config0);
00075     wait_ms(10);
00076     cs = 1;
00077     wait_ms(10);
00078 
00079     cs = 0;
00080     wait_ms(10);
00081     spi.write(WRITE);
00082     spi.write(CNF1);
00083     spi.write(config1);
00084     wait_ms(10);
00085     cs = 1;
00086     wait_ms(10);
00087 
00088     cs = 0;
00089     wait_ms(10);
00090     spi.write(WRITE);
00091     spi.write(CNF2);
00092     spi.write(config2);
00093     wait_ms(10);
00094     cs = 1;
00095     wait_ms(10);
00096 }
00097 
00098 //Method added to enable testing in loopback mode.(pcruce_at_igpp.ucla.edu)
00099 void MCP2515::setMode(MCP2515Mode mode) { //put MCP2515 controller in one of five modes
00100 
00101     //byte writeVal,mask,readVal;
00102     byte writeVal = 0x00;
00103     byte mask = 0x00;
00104 
00105     switch(mode) {
00106       case CONFIGURATION:
00107             writeVal = 0x80;
00108             break;
00109       case NORMAL:
00110           writeVal = 0x00;
00111             break;
00112       case SLEEP:
00113             writeVal = 0x20;
00114           break;
00115     case LISTEN:
00116             writeVal = 0x60;
00117           break;
00118       case LOOPBACK:
00119             writeVal = 0x40;
00120           break;
00121    }
00122 
00123     mask = 0xE0;
00124 
00125     cs = 0;
00126     spi.write(BIT_MODIFY);
00127     spi.write(MCP2515CTRL);
00128     spi.write(mask);
00129     spi.write(writeVal);
00130     cs = 1;
00131 
00132 }
00133 
00134 
00135 void MCP2515::send_0()//transmits buffer 0
00136 {
00137 
00138     //wait_mss removed from SEND command(pcruce_at_igpp.ucla.edu)
00139     //In testing we found that any lost data was from PC<->Serial wait_mss,
00140     //Not MCP2515 Controller/AVR wait_mss.  Thus removing the wait_mss at this level
00141     //allows maximum flexibility and performance.
00142     cs = 0;
00143     spi.write(SEND_TX_BUF_0);
00144     cs = 1;
00145 }
00146 
00147 void MCP2515::send_1()//transmits buffer 1
00148 {
00149     cs = 0;
00150     spi.write(SEND_TX_BUF_1);
00151     cs = 1;
00152 }
00153 
00154 void MCP2515::send_2()//transmits buffer 2
00155 {
00156     cs = 0;
00157     spi.write(SEND_TX_BUF_2);
00158     cs = 1;
00159 }
00160 
00161 char MCP2515::readID_0()//reads ID in recieve buffer 0
00162 {
00163     char retVal;
00164     cs = 0;
00165     wait_ms(10);
00166     spi.write(READ_RX_BUF_0_ID);
00167     retVal = spi.write(0xFF);
00168     wait_ms(10);
00169     cs = 1;
00170     wait_ms(10);
00171     return retVal;
00172 }
00173 
00174 char MCP2515::readID_1()//reads ID in reciever buffer 1
00175 {
00176     char retVal;
00177     cs = 0;
00178     wait_ms(10);
00179     spi.write(READ_RX_BUF_1_ID);
00180     retVal = spi.write(0xFF);
00181     wait_ms(10);
00182     cs = 1;
00183     wait_ms(10);
00184     return retVal;
00185 }
00186 
00187 char MCP2515::readDATA_0()//reads DATA in recieve buffer 0
00188 {
00189     char retVal;
00190     cs = 0;
00191     wait_ms(10);
00192     spi.write( READ_RX_BUF_0_DATA);
00193     retVal = spi.write(0xFF);
00194     wait_ms(10);
00195     cs = 1;
00196     wait_ms(10);
00197     return retVal;
00198 }
00199 
00200 char MCP2515::readDATA_1()//reads data in recieve buffer 1
00201 {
00202     char retVal;
00203     cs = 0;
00204     wait_ms(10);
00205     spi.write( READ_RX_BUF_1_DATA);
00206     retVal = spi.write(0xFF);
00207     wait_ms(10);
00208     cs = 1;
00209     wait_ms(10);
00210     return retVal;
00211 }
00212 
00213     //extending MCP2515 data read to full frames(pcruce_at_igpp.ucla.edu)
00214     //It is the responsibility of the user to allocate memory for output.
00215     //If you don't know what length the bus frames will be, data_out should be 8-bytes
00216 void MCP2515::readDATA_ff_0(byte* length_out,byte *data_out,unsigned short *id_out){
00217 
00218     byte len,i;
00219     unsigned short id_h,id_l;
00220 
00221     cs = 0;
00222     spi.write(READ_RX_BUF_0_ID);
00223     id_h = (unsigned short) spi.write(0xFF); //id high
00224     id_l = (unsigned short) spi.write(0xFF); //id low
00225     spi.write(0xFF); //extended id high(unused)
00226     spi.write(0xFF); //extended id low(unused)
00227     len = (spi.write(0xFF) & 0x0F); //data length code
00228     for (i = 0;i<len;i++) {
00229         data_out[i] = spi.write(0xFF);
00230     }
00231     cs = 1;
00232     (*length_out) = len;
00233     (*id_out) = ((id_h << 3) + ((id_l & 0xE0) >> 5)); //repack identifier
00234     
00235 }
00236 
00237 void MCP2515::readDATA_ff_1(byte* length_out,byte *data_out,unsigned short *id_out){
00238 
00239     byte id_h,id_l,len,i;
00240 
00241     cs = 0;
00242     spi.write(READ_RX_BUF_1_ID);
00243     id_h = spi.write(0xFF); //id high
00244     id_l = spi.write(0xFF); //id low
00245     spi.write(0xFF); //extended id high(unused)
00246     spi.write(0xFF); //extended id low(unused)
00247     len = (spi.write(0xFF) & 0x0F); //data length code
00248     for (i = 0;i<len;i++) {
00249         data_out[i] = spi.write(0xFF);
00250     }
00251     cs = 1;
00252 
00253     (*length_out) = len;
00254     (*id_out) = ((((unsigned short) id_h) << 3) + ((id_l & 0xE0) >> 5)); //repack identifier
00255 }
00256 
00257     //Adding method to read status register
00258     //MCP2515 be used to determine whether a frame was received.
00259     //(readStatus() & 0x80) == 0x80 means frame in buffer 0
00260     //(readStatus() & 0x40) == 0x40 means frame in buffer 1
00261 byte MCP2515::readStatus() 
00262 {
00263     byte retVal;
00264     cs = 0;
00265     spi.write(READ_STATUS);
00266     retVal = spi.write(0xFF);
00267     cs = 1;
00268     return retVal;
00269 
00270 }
00271 
00272 void MCP2515::load_0(byte identifier, byte data)//loads ID and DATA into transmit buffer 0
00273 {
00274     cs = 0;
00275     wait_ms(10);
00276     spi.write(LOAD_TX_BUF_0_ID);
00277     spi.write(identifier);
00278     wait_ms(10);
00279     cs = 1;
00280     wait_ms(10);
00281 
00282     cs = 0;
00283     wait_ms(10);
00284     spi.write(LOAD_TX_BUF_0_DATA);
00285     spi.write(data);
00286     wait_ms(10);
00287     cs = 1;
00288     wait_ms(10);
00289 }
00290 
00291 void MCP2515::load_1(byte identifier, byte data)//loads ID and DATA into transmit buffer 1
00292 {
00293     cs = 0;
00294     wait_ms(10);
00295     spi.write(LOAD_TX_BUF_1_ID);
00296     spi.write(identifier);
00297     wait_ms(10);
00298     cs = 1;
00299     wait_ms(10);
00300 
00301     cs = 0;
00302     wait_ms(10);
00303     spi.write(LOAD_TX_BUF_1_DATA);
00304     spi.write(data);
00305     wait_ms(10);
00306     cs = 1;
00307     wait_ms(10);
00308 }
00309 
00310 void MCP2515::load_2(byte identifier, byte data)//loads ID and DATA into transmit buffer 2
00311 {
00312     cs = 0;
00313     wait_ms(10);
00314     spi.write(LOAD_TX_BUF_2_ID);
00315     spi.write(identifier);
00316     wait_ms(10);
00317     cs = 1;
00318     wait_ms(10);
00319 
00320     cs = 0;
00321     wait_ms(10);
00322     spi.write(LOAD_TX_BUF_2_DATA);
00323     spi.write(data);
00324     wait_ms(10);
00325     cs = 1;
00326     wait_ms(10);
00327 }
00328 
00329 void MCP2515::load_ff_0(byte length,unsigned short identifier,byte *data)
00330 {
00331     
00332     byte i,id_high,id_low;
00333 
00334     //generate id bytes before spi write
00335     id_high = (byte) (identifier >> 3);
00336     id_low = (byte) ((identifier << 5) & 0x00E0);
00337 
00338     cs = 0;
00339     spi.write(LOAD_TX_BUF_0_ID);
00340     spi.write(id_high); //identifier high bits
00341     spi.write(id_low); //identifier low bits
00342     spi.write(0x00); //extended identifier registers(unused)
00343     spi.write(0x00);
00344     spi.write(length);
00345     for (i=0;i<length;i++) { //load data buffer
00346         spi.write(data[i]);
00347     }
00348 
00349     cs = 1;
00350 
00351 }
00352 
00353 void MCP2515::load_ff_1(byte length,unsigned short identifier,byte *data)
00354 {
00355     
00356     byte i,id_high,id_low;
00357 
00358     //generate id bytes before spi write
00359     id_high = (byte) (identifier >> 3);
00360     id_low = (byte) ((identifier << 5) & 0x00E0);
00361 
00362     cs = 0;
00363     spi.write(LOAD_TX_BUF_1_ID);
00364     spi.write(id_high); //identifier high bits
00365     spi.write(id_low); //identifier low bits
00366     spi.write(0x00); //extended identifier registers(unused)
00367     spi.write(0x00);
00368     spi.write(length);
00369     for (i=0;i<length;i++) { //load data buffer
00370         spi.write(data[i]);
00371     }
00372 
00373     cs = 1;
00374 
00375 
00376 }
00377 
00378 void MCP2515::load_ff_2(byte length,unsigned short identifier,byte *data)
00379 {
00380     
00381     byte i,id_high,id_low;
00382 
00383     //generate id bytes before spi write
00384     id_high = (byte) (identifier >> 3);
00385     id_low = (byte) ((identifier << 5) & 0x00E0);
00386 
00387     cs = 0;
00388 
00389     spi.write(LOAD_TX_BUF_2_ID);
00390     spi.write(id_high); //identifier high bits
00391     spi.write(id_low); //identifier low bits
00392     spi.write(0x00); //extended identifier registers(unused)
00393     spi.write(0x00);
00394     spi.write(length); //data length code
00395     for (i=0;i<length;i++) { //load data buffer
00396         spi.write(data[i]);
00397     }
00398 
00399     cs = 1;
00400 
00401 }
00402 
00403 //------------------------------------------------------------------------------
00404 //Added for ram
00405 void MCP2515::writeRegister(byte address, byte data)
00406 {
00407     cs = 0;
00408     wait_ms(10);
00409     spi.write(WRITE);
00410     spi.write(address);
00411     spi.write(data);
00412     wait_ms(10);
00413     cs = 1;
00414     wait_ms(10);
00415 }
00416 void MCP2515::readRegister(byte address, byte *data_out)
00417 {
00418     cs = 0;
00419     wait_ms(10);
00420     spi.write(READ);
00421     spi.write(address);
00422     *data_out = spi.write(0xFF);
00423     wait_ms(10);
00424     cs = 1;
00425     wait_ms(10);
00426 }
00427 
00428 void MCP2515::reset()
00429 {
00430     cs = 0;
00431     wait_ms(10);
00432     spi.write(RESET_REG);
00433     wait_ms(10);
00434     cs = 1;
00435     wait_ms(10);
00436 }
00437 
00438 byte MCP2515::readRXStatus()
00439 {
00440     byte retVal;
00441     cs = 0;
00442     spi.write(RX_STATUS);
00443     retVal = spi.write(0xFF);
00444     cs = 1;
00445     return retVal;
00446 }
00447 
00448 void MCP2515::bitModify(byte address, byte mask, byte data)
00449 {
00450     cs = 0;
00451     spi.write(BIT_MODIFY);
00452     spi.write(address);
00453     spi.write(mask);
00454     spi.write(data);
00455     cs = 1;
00456 }
00457 
00458 void MCP2515::setMask(unsigned short identifier)
00459 {
00460     setMask_0(identifier);
00461     setMask_1(identifier);
00462 }
00463 
00464 void MCP2515::setMask_0(unsigned short identifier)
00465 {
00466     writeRegister(RXM0SIDH, (byte)(identifier>>3));
00467     writeRegister(RXM0SIDL, (byte)(identifier<<5));
00468 }
00469 
00470 void MCP2515::setMask_1(unsigned short identifier)
00471 {
00472     writeRegister(RXM1SIDH, (byte)(identifier>>3));
00473     writeRegister(RXM1SIDL, (byte)(identifier<<5));
00474 }