Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DISCO-F746NG_rtos_test
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 }
Generated on Tue Jul 12 2022 14:07:53 by
1.7.2